ImageProcess.cpp
Upload User: whhzxy
Upload Date: 2022-01-20
Package Size: 7k
Code Size: 6k
Category:

OpenCV

Development Platform:

C/C++

  1. #include <cv.h>
  2. #include <highgui.h>
  3. #include <math.h>
  4. //#include <stdlib.h>
  5. #include <stdio.h>
  6. int main(int argc, char* argv[])
  7. {
  8.     IplImage *src = 0; //定义源图像指针
  9. IplImage *src_smooth = 0; // define the smooth image pointer;
  10.     IplImage *tmp = 0; //定义临时图像指针
  11.     IplImage *src_back = 0; //定义源图像背景指针
  12.     IplImage *dst_gray = 0; //定义源文件去掉背景后的目标灰度图像指针
  13.     IplImage *dst_bw = 0; //定义源文件去掉背景后的目标二值图像指针
  14.     IplImage *dst_contours = 0; //定义轮廓图像指针
  15.     IplConvKernel *element = 0; //定义形态学结构指针
  16.     int Number_Object =0; //定义目标对象数量
  17.     int contour_area_tmp = 0; //定义目标对象面积临时寄存器
  18.     int contour_area_sum = 0; //定义目标所有对象面积的和
  19.     int contour_area_ave = 0; //定义目标对象面积平均值
  20.     int contour_area_max = 0; //定义目标对象面积最大值
  21.     CvMemStorage *stor = 0;
  22.     CvSeq * cont = 0;
  23.     CvContourScanner contour_scanner; 
  24.     CvSeq * a_contour= 0;
  25.     // 【读取和显示图像】
  26.     // the first command line parameter must be image file name 
  27.     if ( argc == 2 && (src = cvLoadImage(argv[1], -1))!=0 )
  28.     {
  29.         
  30.     }
  31.     else
  32.     {
  33. src = cvLoadImage("d:\rice.png", 0);
  34.     }
  35.     cvNamedWindow( "src", CV_WINDOW_AUTOSIZE );
  36.     cvShowImage( "src", src );
  37. // 【平滑图像】
  38. src_smooth = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
  39. //         输入图像,输出图像,平滑方法,参数1234
  40.     //cvSmooth(src, src_smooth, CV_BLUR, 3,3, 0, 0);
  41. //cvSmooth(src, src_smooth, CV_MEDIAN, 3, 3, 0, 0);
  42. //cvSmooth(src, src_smooth, CV_GAUSSIAN, 3, 3, 0, 0);
  43. cvSmooth(src, src_smooth, CV_BILATERAL, 10,10,30,30);//效果最好,保留轮廓滤除噪声;
  44. //display the smooth image;
  45. cvNamedWindow( "src_smooth", CV_WINDOW_AUTOSIZE );
  46.     cvShowImage( "src_smooth", src_smooth );
  47.     // 【估计图像背景】
  48.     tmp = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);
  49.     src_back = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);    
  50.     element = cvCreateStructuringElementEx( 4, 4, 1, 1, CV_SHAPE_ELLIPSE, 0);//创建结构元素
  51.     
  52. //用该结构对源图象进行数学形态学的开操作后,估计背景亮度
  53. //事实上,先腐蚀再膨胀就是把图像去掉了,事实上,可以作同位操作,下面两种做法都可以,但似乎不对称操作效果更好;
  54.     //cvErode( src_smooth, tmp, element, 12);//先腐蚀
  55.     //cvDilate( tmp, src_back, element, 12);//再膨胀
  56. cvErode( src_smooth, src_back, element, 20);//先腐蚀
  57.     cvDilate( src_back, src_back, element, 60);//再膨胀
  58.     cvNamedWindow( "src_back", CV_WINDOW_AUTOSIZE );
  59.     cvShowImage( "src_back", src_back );
  60.     //【从源图象中减区背景图像】
  61.     dst_gray = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);
  62.     cvSub( src_smooth, src_back, dst_gray, 0);//计算两个数组每个元素的差
  63.     cvNamedWindow( "dst_gray", CV_WINDOW_AUTOSIZE );
  64.     cvShowImage( "dst_gray", dst_gray );
  65.     //【使用阀值操作将图像转换为二值图像】
  66.     dst_bw = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);
  67.     cvThreshold( dst_gray, dst_bw ,50, 255, CV_THRESH_BINARY ); //取阀值为50把图像转为二值图像
  68.     //cvAdaptiveThreshold( dst_gray, dst_bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 5 );
  69.     cvNamedWindow( "dst_bw", CV_WINDOW_AUTOSIZE );
  70.     cvShowImage( "dst_bw", dst_bw );    
  71. // 【检查图像中的目标对象数量】
  72.     stor = cvCreateMemStorage(0);//创建内存块,默认值64K大小
  73.     cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), stor); //创建序列
  74. //在二值图像中寻找轮廓
  75. //二值图像(cvThreshold二值化),内存,序列,
  76.     Number_Object = cvFindContours( dst_bw, stor, &cont, sizeof(CvContour), 
  77. //轮廓提取方法(提取所有轮廓),轮廓逼近方法(只保留末端像素点),像素偏移量
  78. CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); 
  79.     printf("Number_Object: %dn", Number_Object);
  80.     //【计算图像中对象的统计属性】
  81.     dst_contours = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);
  82.     cvThreshold( dst_contours, dst_contours ,0, 255, CV_THRESH_BINARY ); //在画轮廓前先把图像变成白色
  83. //两种写法,可以省略cont->first为;
  84. //for(;cont;cont=cont->h_next)
  85. for(cont->first;cont;cont=cont->h_next)
  86.     {
  87. //绘制当前轮廓
  88.         cvDrawContours( dst_contours, cont, CV_RGB(255, 255,255), CV_RGB(0, 0, 255), 0, 1, 8, cvPoint(0, 0) ); 
  89. //cvContourArea 计算整个轮廓或部分轮廓的面积
  90. //轮廓,感兴趣的轮廓(部分)的起始点(CvSlice为序列分割,默认为整个序列/轮廓)
  91. //cvContourArea( const CvArr* contour,CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ))
  92.         contour_area_tmp = fabs(cvContourArea( cont, CV_WHOLE_SEQ )); //获取当前轮廓面积
  93.         if( contour_area_tmp > contour_area_max )
  94.         {
  95.             contour_area_max = contour_area_tmp; //找到面积最大的轮廓
  96.         }
  97.         contour_area_sum = contour_area_sum+contour_area_tmp; //求所有轮廓的面积和
  98.     }
  99.     contour_area_ave = contour_area_sum/ Number_Object; //求出所有轮廓的平均值
  100.     printf("contour_area_ave: %dn", contour_area_ave );
  101.     printf("contour_area_max: %dn", contour_area_max );
  102. printf("contour_area_total: %dn",contour_area_sum);
  103.     cvNamedWindow( "dst_contours", CV_WINDOW_AUTOSIZE );
  104.     cvShowImage( "dst_contours", dst_contours );
  105.     //等待退出,如果是0或负数,随便用键盘按某个键,退出,执行下面的程序;
  106. //如果是某个正数,则等待 XXX毫秒退出,此处为等待1s。
  107. //cvWaitKey(1000);
  108. //下面则是特定按键 ESC才退出,注意要用到while{}
  109. while(1){
  110.  int key = cvWaitKey(0);
  111.  if(key==27){break;}
  112. }
  113.     cvReleaseImage(&src);
  114. cvReleaseImage(&src_smooth);
  115.     cvReleaseImage(&tmp);
  116.     cvReleaseImage(&src_back);
  117.     cvReleaseImage(&dst_gray);
  118.     cvReleaseImage(&dst_bw);
  119.     cvReleaseImage(&dst_contours);
  120.     cvReleaseMemStorage(&stor);
  121.     cvDestroyWindow( "src" );
  122. cvDestroyWindow("src_smooth");
  123.     cvDestroyWindow( "src_back" );
  124.     cvDestroyWindow( "dst_gray" );
  125.     cvDestroyWindow( "dst_bw" );
  126.     cvDestroyWindow( "dst_contours" );
  127.     //void cvDestroyAllWindows(void);
  128.     return 0;
  129. }