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个数量级……学识浅薄,有没有大佬可以讲解一下(^_^)??

 

posted @ 2019-06-03 13:35  星海violet  阅读(860)  评论(0编辑  收藏  举报