1. 程式人生 > >opencv——對象計數

opencv——對象計數

cast ber iostream 椒鹽噪聲 char* image lur code clas

技術分享圖片

思路:

1、通過形態學操作、閾值處理距離變換等方法,使得各個輪廓分開

2、計算輪廓數量

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 #include <math.h>
 4 
 5 using namespace cv;
 6 using namespace std;
 7 
 8 
 9 int main(int argc, char** argv)
10 {
11     Mat src = imread("計數.jpg");
12     //medianBlur(src, src,5);
//中值濾波,去除椒鹽噪聲 13 imshow("src", src); 14 15 Mat src_gray,binary; 16 17 cvtColor(src,src_gray,COLOR_BGR2GRAY); 18 19 threshold(src_gray,binary,0,255,THRESH_BINARY|THRESH_TRIANGLE);//顏色單一時,使用THRESH_TRIANGLE比OTSU好 20 imshow("binary", binary); 21 22 //形態學操作 23 Mat kernel = getStructuringElement(MORPH_RECT,Size(5
,5)); 24 dilate(binary, binary, kernel,Point(-1,-1),4); 25 26 //距離變換 27 Mat dist; 28 bitwise_not(binary, binary);//取反 29 distanceTransform(binary,dist,CV_DIST_L2,3); 30 normalize(dist, dist,0,1.0,NORM_MINMAX); 31 imshow("dist", dist); 32 33 //閾值化二值分割 34 //threshold(dist, dist,0.7,1.0,THRESH_BINARY);
//對距離進行篩選,去除邊緣部分 35 //normalize(dist, dist, 0, 255, NORM_MINMAX); 36 Mat dist_8U; 37 dist.convertTo(dist_8U,CV_8U); 38 adaptiveThreshold(dist_8U, dist_8U, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//自適應閾值,代替上面的閾值操作 39 //形態學操作,使得斷開部分連接 40 kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1)); 41 dilate(dist_8U, dist_8U, kernel, Point(-1, -1),3); 42 43 imshow("dist_8U", dist_8U); 44 45 // 連通區域計數 46 vector<vector<Point>> contours; 47 findContours(dist_8U, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 48 49 // draw result 50 Mat markers = Mat::zeros(src.size(), CV_8UC3); 51 RNG rng(12345); 52 for (size_t t = 0; t < contours.size(); t++) { 53 drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 54 -1, 8, Mat()); 55 } 56 printf("number of corns : %d", contours.size()); 57 imshow("Final result", markers); 58 59 waitKey(0); 60 61 return 0; 62 }

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
Mat src = imread("計數.jpg");
//medianBlur(src, src,5);//中值濾波,去除椒鹽噪聲
imshow("src", src);

Mat src_gray,binary;

cvtColor(src,src_gray,COLOR_BGR2GRAY);

threshold(src_gray,binary,0,255,THRESH_BINARY|THRESH_TRIANGLE);//顏色單一時,使用THRESH_TRIANGLE比OTSU好
imshow("binary", binary);

//形態學操作
Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5));
dilate(binary, binary, kernel,Point(-1,-1),4);

//距離變換
Mat dist;
bitwise_not(binary, binary);//取反
distanceTransform(binary,dist,CV_DIST_L2,3);
normalize(dist, dist,0,1.0,NORM_MINMAX);
imshow("dist", dist);

//閾值化二值分割
//threshold(dist, dist,0.7,1.0,THRESH_BINARY);//對距離進行篩選,去除邊緣部分
//normalize(dist, dist, 0, 255, NORM_MINMAX);
Mat dist_8U;
dist.convertTo(dist_8U,CV_8U);
adaptiveThreshold(dist_8U, dist_8U, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//自適應閾值,代替上面的閾值操作
//形態學操作,使得斷開部分連接
kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
dilate(dist_8U, dist_8U, kernel, Point(-1, -1),3);

imshow("dist_8U", dist_8U);

// 連通區域計數
vector<vector<Point>> contours;
findContours(dist_8U, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

// draw result
Mat markers = Mat::zeros(src.size(), CV_8UC3);
RNG rng(12345);
for (size_t t = 0; t < contours.size(); t++) {
drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),
-1, 8, Mat());
}
printf("number of corns : %d", contours.size());
imshow("Final result", markers);

waitKey(0);

return 0;
}


opencv——對象計數