opencv区域标记数大米粒

Posted lyqf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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个数量级……学识浅薄,有没有大佬可以讲解一下(^_^)??

 

以上是关于opencv区域标记数大米粒的主要内容,如果未能解决你的问题,请参考以下文章

大米粒计数基于matlab GUI形态学大米粒颗粒识别含Matlab源码 915期

opencv中的图形查找统计米粒数量

opencv使用——玉米粒识别和优劣判断

每个网页的最大 <iFrame> 标记数

如何用matlab 画散点图 如何标记数据点的颜色

opencv怎么截取视频图片