opencv区域标记数大米粒
数大米粒,
区域标记,利用八连通算法,进行出栈入栈操作
需要用中值滤波消除噪声
1 #include <iostream> 2 #include <vector> 3 #include<stack> 4 #include <map> 5 #include <windows.h> 6 #include <opencv2/imgproc/imgproc.hpp> 7 #include <opencv2/highgui/highgui.hpp> 8 using namespace std; 9 using namespace cv; 10 11 stack<pair<int,int>>pos;//存当前位置,栈 12 pair<int, int>Element; 13 int vis[260][260] = { 0 }; 14 int num = 0;//计数 15 void countRice(Mat &src) 16 { 17 num = 0; 18 memset(vis, 0, sizeof(vis)); 19 int row = src.rows; 20 int col = src.cols; 21 22 for (int i = 0; i < row; i++) 23 { 24 //uchar* data = src.ptr<uchar>(i); 25 for (int j = 0; j < col; j++) 26 { 27 //src.at<uchar>(j,i) == 255 与data[j]的区别 28 if (vis[i][j] == 0 && src.at<uchar>(j,i) == 255) {//该点为白色 29 vis[i][j] = 1; 30 Element = make_pair(i, j); 31 pos.push(Element); 32 num++;//计数 33 } 34 35 while(!pos.empty()) 36 { 37 pair<int, int>aaa = pos.top(); 38 int xx = aaa.first;//row 39 int yy = aaa.second;//col 40 pos.pop(); 41 int x = xx ;int y = yy + 1;//上方 42 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y,x) == 255 && vis[x][y] == 0) 43 { 44 vis[x][y] = 1; 45 Element = make_pair(x, y); 46 pos.push(Element); 47 } 48 49 x = xx - 1; y = yy;//左方 50 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) == 255 && vis[x][y] == 0) 51 { 52 vis[x][y] = 1; 53 Element = make_pair(x, y); 54 pos.push(Element); 55 } 56 57 x = xx ; y = yy-1;//下方 58 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) ==255 && vis[x][y] == 0) 59 { 60 vis[x][y] = 1; 61 Element = make_pair(x, y); 62 pos.push(Element); 63 } 64 65 x = xx + 1; y = yy;//右方 66 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x)==255 && vis[x][y] == 0) 67 { 68 vis[x][y] = 1; 69 Element = make_pair(x, y); 70 pos.push(Element); 71 } 72 x = xx + 1; y = yy + 1; 73 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) == 255 && vis[x][y] == 0) 74 { 75 vis[x][y] = 1; 76 Element = make_pair(x, y); 77 pos.push(Element); 78 } 79 x = xx - 1; y = yy - 1; 80 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) == 255 && vis[x][y] == 0) 81 { 82 vis[x][y] = 1; 83 Element = make_pair(x, y); 84 pos.push(Element); 85 } 86 x = xx + 1; y = yy - 1; 87 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) == 255 && vis[x][y] == 0) 88 { 89 vis[x][y] = 1; 90 Element = make_pair(x, y); 91 pos.push(Element); 92 } 93 x = xx - 1; y = yy + 1; 94 if (x >= 0 && x < row&&y >= 0 && y < col&& src.at<uchar>(y, x) == 255 && vis[x][y] == 0) 95 { 96 vis[x][y] = 1; 97 Element = make_pair(x, y); 98 pos.push(Element); 99 } 100 } 101 } 102 } 103 cout << num << endl; 104 } 105 106 int main() 107 { 108 Mat src = imread("C:\\图7-26(a).jpg",IMREAD_GRAYSCALE);//读取灰度图 109 Mat binImg(src.size(),src.type());//初始化 110 threshold(src, binImg, 130, 255, THRESH_BINARY);//背景灰度值大于130,设为255,否则为0(白色为255,黑色为0) 111 namedWindow("原图"); 112 imshow("原图", src); 113 namedWindow("二值图像"); 114 imshow("二值图像", binImg); 115 116 cout << "去噪前"<<endl; 117 countRice(binImg);//计算个数 118 //中值滤波去噪 119 Mat out; 120 medianBlur(binImg, out, 3); 121 namedWindow("输出计数图像"); 122 imshow("输出计数图像", out); 123 124 //8连通标记 125 cout << "去噪后" << endl; 126 countRice(out);//计算个数 127 128 waitKey(0); 129 return 0; 130 }
结果:
遇到的问题:
uchar* data = src.ptr<uchar>(i);//获取图像第i行地址
data[j]获取的像素值与
src.at<uchar>(j,i)获取的像素值
貌似不一样,计算的结果差3个数量级……学识浅薄,有没有大佬可以讲解一下(^_^)??