首页 > 其他 > 详细

数米粒--函数调用

时间:2021-05-01 16:36:59      阅读:17      评论:0      收藏:0      [点我收藏+]

1.函数了解-->

读取图片:IplImage* cvLoadImage( const char* filename, int flags=CV_LOAD_IMAGE_COLOR );

创建结构元:IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchor_x, int anchor_y,int shape, int* values=NULL );

  shape是自定义核的形状,具体为

  1.CV_SHAPE_RECT  核是矩形

  2.CV_SHAPE_CROSS 核是勺子交叉形

  3.CV_SHAPE_ELLIPSE 核是椭圆形

  4.CV_SHAPE_CUSTOM 核是用户自定义类型

二值化(相当于阈值处理):void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type );

腐蚀void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );

膨胀:void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );   (最后一个参数表示腐蚀/膨胀的次数)

顶帽变换:原始图像减去其开运算的图像 而开运算可用于补偿不均匀的背景亮度,所以用一个大的结构元素做开运算后 然后用原图像减去这个开运算,就得到了背景均衡的图像。

开操作:先腐蚀,后膨胀。

二值图像中检索轮廓,并返回检测到的轮廓的个数(百度):int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,int header_size=sizeof(CvContour),int mode=CV_RETR_LIST,int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );

轮廓绘制:void cvDrawContours( CvArr *img, CvSeq* contour,CvScalar external_color, CvScalar hole_color,int max_level, int thickness=1,int line_type=8, CvPoint offset=cvPoint(0,0) );

轮廓面积计算:double cvContourArea( const CvArr* contour, CvSliceslice=CV_WHOLE_SEQ );

轮廓周长计算:double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 );

 

2.实验步骤:

  1.得到原始图片;

  2.去除背景干扰(顶帽变换);

  3.二值化(阈值处理);

  4.开操作(去除噪声,删除较小的噪声点);

  5.寻找连通域,计算米粒个数(可以认为合适的处理之后,一个连通域就代表着一个米粒);

  6.查找最大面积的米粒(认为是最大的米粒),对所有轮廓进行标记,对最大轮廓描红标记;

  7.输出米粒个数、最大米粒面积和周长。

 

3.结果:

        原图                背景图            去背景图

技术分享图片    技术分享图片     技术分享图片技术分享图片    技术分享图片     技术分享图片
      二值化后图            开操作处理后              轮廓图

 技术分享图片   结果图

 

4.代码(VC6.0,OpenCV):

技术分享图片
 1 #include "stdio.h"
 2 #include "cv.h"
 3 #include "highgui.h"
 4 
 5 
 6 int main(int arge,char * argv[])
 7 {
 8     char root_path[150];    // 米粒图片路径
 9     IplImage *src, *backImg, *backRImg, *cutImg, *finallyImg, *dst_contours;
10     // 获取原图像
11     sprintf(root_path, "E:\\4_大三下\\机器视觉\\实验图片\\rice.jpg");
12     src = cvLoadImage(root_path,CV_LOAD_IMAGE_GRAYSCALE);            // 原始图片--灰度方式读取
13     backImg = cvLoadImage(root_path,CV_LOAD_IMAGE_GRAYSCALE);        // 背景图片
14     backRImg = cvLoadImage(root_path,CV_LOAD_IMAGE_GRAYSCALE);        // 存放去背景图片
15     cutImg = cvLoadImage(root_path,CV_LOAD_IMAGE_GRAYSCALE);
16     finallyImg = cvLoadImage(root_path,CV_LOAD_IMAGE_GRAYSCALE);
17     dst_contours = cvLoadImage(root_path);
18 
19 
20     // 图像处理
21     IplConvKernel * element = cvCreateStructuringElementEx(4,4,1,1,CV_SHAPE_ELLIPSE,0);        // 形态学构建指针[创建结构元素,4*4,椭圆形]
22     cvErode(src,backImg,element,5);                // 腐蚀
23     cvDilate(backImg,backImg,element,5);        // 膨胀
24     cvSub(src,backImg,backRImg,0);                // 去背景--综合为顶帽变换
25     cvThreshold(backRImg,cutImg,50,255,CV_THRESH_BINARY);        // 二值化函数
26     cvErode(cutImg,finallyImg,element,1);            // 腐蚀
27     cvDilate(finallyImg,finallyImg,element,1);        // 膨胀--综合为一次开操作,去除噪声(较小突出部分)
28     // 寻找连通域,计算米粒个数
29     CvMemStorage * stor = cvCreateMemStorage(0);        // 容器
30     CvSeq * cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);
31     CvSeq * cont1 = cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);
32     // 二值图像中提取轮廓,返回值为轮廓的数目
33     int numberOfObject = cvFindContours(finallyImg,stor,&cont,sizeof(CvContour),CV_RETR_TREE);
34     printf("米粒数目为 :%d \n",numberOfObject);
35     // 遍历轮廓,并画出外轮廓
36     int max_area = 0;
37     int max_length = 0;
38     for(;cont != NULL;cont = cont->h_next) {
39         CvRect rect = cvBoundingRect(cont,0);
40         double tmpArea = fabs(cvContourArea(cont,CV_WHOLE_SEQ));
41         double tmpLength = cvArcLength(cont);
42         if(max_area < tmpArea) {
43             max_area = tmpArea;
44             max_length = tmpLength;
45             cont1 = cont;
46         }
47 //        if(tmpArea > 0) {
48             cvDrawContours(dst_contours,cont,CV_RGB(0,255,0),CV_RGB(255,0,0),0,1,8,cvPoint(0,0));
49 //        }
50     }
51     cvDrawContours(dst_contours,cont1,CV_RGB(255,0,0),CV_RGB(255,0,0),0,1,8,cvPoint(0,0));
52     printf("最大米粒的面积 area = %d , 周长 perimeter = %d \n",max_area,max_length);
53 
54 
55     // 图像显示
56     cvNamedWindow("src");
57     cvShowImage("src",src);
58 //    cvNamedWindow("back");
59 //    cvShowImage("back",backImg);
60 //    cvNamedWindow("backR");
61 //    cvShowImage("backR",backRImg);
62     cvNamedWindow("cut");
63     cvShowImage("cut",cutImg);
64 //    cvNamedWindow("finallyImg");
65 //    cvShowImage("finallyImg",finallyImg);
66     cvNamedWindow("dst_contours");
67     cvShowImage("dst_contours",dst_contours);
68 
69     cvWaitKey(0);
70     return 0;
71 }
View Code

2021-05-01

数米粒--函数调用

原文:https://www.cnblogs.com/2015-16/p/14724252.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!