欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(三)OpenCV图像处理_04_对象计数

程序员文章站 2024-01-27 17:09:52
...
  1. 计算对象个数
    通过二值分割+形态学处理+距离变换+形态学变换(具体问题具体分析)+连通区域计算
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
	Mat src,temp,temp_mor,temp_dist,dst;
	src = imread("../path.jpg",IMREAD_GRAYSCALE);
	if (src.empty())
	{
		cout << "could not load image..." << endl;
		return -1;
	}

	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);
	//通过二值分割
	threshold(src, temp, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
	//imshow("Threshold", temp);
	
	//形态学处理
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	dilate(temp, temp_mor, kernel, Point(-1, -1), 1);//膨胀
	//imshow("MorphShape", temp_mor);
	
	//距离变换
	bitwise_not(temp_mor, temp_mor);//取反,物体变白,背景变黑
	distanceTransform(temp_mor, temp_dist, DIST_L2, 3);
	normalize(temp_dist, temp_dist, 0, 0.9, NORM_MINMAX);
	imshow("Distance", temp_dist);
	
	// 阈值化二值分割
	Mat temp_dist_8u;
	temp_dist.convertTo(temp_dist_8u, CV_8U);
	//threshold(temp_dist_8u, temp_dist_8u, 0.5, 1, THRESH_BINARY);//使用阈值,再次二值化,得到标记
	adaptiveThreshold(temp_dist_8u, temp_dist_8u, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY,81, 0);//使用自适应阈值,再次二值化,得到标记
	//erode(temp_dist_8u, temp_dist_8u, kernel, Point(-1, -1), 1);
	dilate(temp_dist_8u, temp_dist_8u, kernel, Point(-1, -1), 3);//形态学操作,分割各个连通区域

	imshow("Dilate", temp_dist_8u);
	
	//连通区域计算
	vector<vector<Point>> contours;
	findContours(temp_dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);//寻找(外部)轮廓
	
	dst = Mat::zeros(src.size(), CV_8UC3);
	RNG rng;
	for (size_t i = 0; i < contours.size(); i++)
	{
		//绘制轮廓
		drawContours(dst, contours, static_cast<int>(i), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),-1, 8);
	}
	cout << "共有轮廓:" << contours.size() << endl;
	imshow("Final", dst);

	waitKey(0);
	return 0;
}

src为:
(三)OpenCV图像处理_04_对象计数
输出结果为:
(三)OpenCV图像处理_04_对象计数