图1:原图 图2:阈值化 图3:黄色圆圈标记结果
请点击超练级获取图像地址
实现过程:我对这个演示Demo做个大概介绍,图中圆斑重叠区域较少,因此处理难度也较小,充其量只能做个演示作用;再次,程序中的分割阈值也是几经尝试认为确定的,没有使用自适应阈值化;经观察图中目标的面积特征较为明显,因此最后的结果是根据面积特征得出的(当然目标和背景的颜色差异也是较大的,也可以作为特征使用,本人未做验证)。基本流程如下:
- 将图像灰度化;cvtColor()
- 对图像进行平滑处理,减少噪声;blur()
- 对图像进行阈值化处理;threshold(),效果见图2
- 提取图像中目标的轮廓,分析了轮廓的周长和面积,可以的话,可以建立目标面积特征的直方图,可以根据直方图进行自适应选取特征阈值,但是本程序没有采用直方图,而是根据观察做出的阈值。
- 根据面积阈值,在原图中标记目标,效果见图3。从图中看,目标基本上都识别出来了,但是也有一些错误识别。
下面是本演示项目的程序:
/************************************************* ***matching_test.cpp ***Created on: Oct 17, 2010 ***Author: ethan *************************************************/ /************************************************* **************************************************/ #pragma warning (disable:4786) //#pragma comment () /*************************************************/ #include "opencv2/opencv.hpp" #include "opencv2/core/core.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/nonfree/features2d.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/stitching/stitcher.hpp" #include "opencv2/stitching/warpers.hpp" #include <map> #include <math.h> #include <time.h> #include <stdlib.h> #include <vector> #include <iostream> #include <Windows.h> /***命名空间***/ using namespace cv; using namespace std; /*************************/ /*************************/ int main( int argc, char** argv ) { Mat src; src = imread("test1.jpg"); resize(src,src,Size(640,480)); Mat gray; cvtColor(src,gray,CV_BGR2GRAY); blur(gray,gray,Size(13,13)); imshow("Gray Image",gray); Mat thresh; threshold(gray,thresh,90,255,THRESH_BINARY); imshow("Thresholded Image",thresh); imwrite("thresh.jpg",thresh); vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(thresh,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); Mat src_show = src.clone(); for(int i = 0; i < contours.size(); i++) { float length = arcLength(contours[i],true); float area = contourArea(contours[i],false); if(area > 10 && area < 800) { drawContours(src_show,contours,i,Scalar(0,236,255)); cout << "contour[" << i << "] = " << length << endl; cout << "Area[" << i << "] = " << area << endl; imshow("src_show",src_show); waitKey(2000); } } imwrite("result.jpg",src_show); waitKey(0); system("pause"); }