(三)OpenCV图像处理_04_对象计数
程序员文章站
2024-01-27 17:09:52
...
- 计算对象个数
通过二值分割+形态学处理+距离变换+形态学变换(具体问题具体分析)+连通区域计算
#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为:
输出结果为:
上一篇: python+django 实现从服务器下载pdf文档的功能
下一篇: 使用ssh进行代理转发设置