OpenCV实践:玉米计数

1、要求:利用opencv对如下图片中的玉米颗粒计数

OpenCV实践:玉米计数_第1张图片

2、思路

  1. 二值分割
  2. 形态学处理
  3. 距离变换
  4. 阈值化二值分割(局部AdaptiveThreshold每个区域都有一个阈值)
  5. 连通区域计数(利用findContours查找轮廓并计数)

3、代码实践

#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
	Mat grayimg, BinaryImg, morhImage;
	Mat img = imread("D://04.jpg");
	imshow("原图", img);
	//二值化操作
	cvtColor(img, grayimg, COLOR_BGR2GRAY);
	threshold(grayimg, BinaryImg, 100, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("二值化", BinaryImg);

	//形态学腐蚀
	Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 15));
	dilate(BinaryImg, morhImage, kernel);
	imshow("morphology", morhImage);

	//距离变换:用于二值化图像中的每一个非零点距自己最近的零点的距离,距离变换图像上越亮的点,代表了这一点距离零点的距离越远。
	Mat dist;
	bitwise_not(morhImage, morhImage);
	distanceTransform(morhImage, dist, CV_DIST_L2, 3);
	normalize(dist, dist, 0, 1.0, NORM_MINMAX);   //范围在0~1之间
	imshow("distance", dist);

	//形态学处理
	Mat MorphImg;
	dist.convertTo(MorphImg, CV_8U);
	//threshold(MorphImg, MorphImg, 0.8, 255, THRESH_BINARY);  //上面像素值在0~1之间
	adaptiveThreshold(MorphImg, MorphImg, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//使用这个比threshold效果好,
	kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));
	morphologyEx(MorphImg, MorphImg, MORPH_DILATE, kernel);  //开操作
	imshow("t-distance", MorphImg);

	//找到种子的轮廓区域
	vector> contours;
	findContours(MorphImg, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	// draw result
	Mat markers = Mat::zeros(img.size(), CV_8UC3);
	RNG rng(12345);     //随机产生颜色
	for (int i = 0; i < contours.size(); i++)
	{
		drawContours(markers, contours, i, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, Mat());
	}
	cout << "number of corns: " << contours.size() << endl;
	imshow("result Img", markers);

	waitKey(0);
}

OpenCV实践:玉米计数_第2张图片

OpenCV实践:玉米计数_第3张图片

OpenCV实践:玉米计数_第4张图片

OpenCV实践:玉米计数_第5张图片

你可能感兴趣的:(opencv)