图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");
}