- #include <stdio.h>
- #include "cv.h"
- #include "cxcore.h"
- #include "highgui.h"
- #include <iostream>
- using namespace std;
- #pragma comment(lib,"cv.lib")
- #pragma comment(lib,"cxcore.lib")
- #pragma comment(lib,"highgui.lib")
- struct Position
- {
- int x,y;
- };
- double per[256];// 保存灰度概率
- IplImage *FindCountours(IplImage* src,IplImage *pContourImg);
- int ImageStretchByHistogram(IplImage *src,IplImage *dst);
- IplImage* Hist_Equalization(IplImage *srcimg);
- void proBorder(IplImage *src); // 边界的处理
- void GetBackImage(IplImage* src,IplImage* src_back);
- void Threshold(IplImage *src);
- int GetThreshold(double *const prob);
- void Getprobability(IplImage *src);
- double Eccentricity(IplImage *src);
- void main()
- {
- //IplImage * src = cvLoadImage("C:\\image19\\A634.jpg",-1);//灰度图的方式载入
- IplImage * src = cvLoadImage("C:\\image19\\A857.jpg",-1);
- IplImage * dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
- IplImage *src_back = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,src->nChannels);
- GetBackImage(src,src_back);
- dst = FindCountours(src_back,dst);
- cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
- cvShowImage("test",dst);
- cvWaitKey(0);
- cvReleaseImage(&src);
- cvReleaseImage(&dst);
- }
- void GetBackImage(IplImage* src,IplImage* src_back)
- {
- //cvCvtColor(src,src,CV_RGB2GRAY);//灰度化
- IplImage *tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
- // 创建结构元素
- IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
- //用该结构对源图象进行数学形态学的开操作后,估计背景亮度
- cvErode(src,tmp,element,9);
- //使用任意结构元素腐蚀图像
- cvDilate(tmp,src_back, element,9);
- //使用任意结构元素膨胀图像
- }
- IplImage *FindCountours(IplImage* src,IplImage *pContourImg)
- {
- CvMemStorage *storage = cvCreateMemStorage(0); //提取轮廓需要的储存容量为默认KB
- CvSeq * pcontour = 0; //提取轮廓的序列指针
- IplImage *temp = cvCreateImage(cvGetSize(src),src->depth,1);
- //cvSmooth(src,temp,CV_GAUSSIAN,3,1,0);
- cvSmooth(src,src,CV_GAUSSIAN,3,1,0);//平滑处理
- cvCvtColor(src,temp,CV_RGB2GRAY);//灰度化
- Getprobability(temp);
- printf("最好的阈值:%d\n",GetThreshold(per));
- //Threshold(temp);
- proBorder(temp);
- cvThreshold(temp,temp,GetThreshold(per),255,CV_THRESH_BINARY_INV);
- int contoursNum = 0; // 轮廓数量
- //int mode = CV_RETR_LIST;
- int mode = CV_RETR_EXTERNAL;// 提取最外层轮廓
- contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),mode,CV_CHAIN_APPROX_NONE);
- // contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
- //二值图, 得到轮廓存储,轮廓指针序列,header_size,提取模式,逼近方法
- CvScalar externalColor;// 保存颜色值
- CvScalar holeColor;
- //————–画轮廓—————-//
- for (; pcontour != 0; pcontour=pcontour -> h_next)
- {
- //holeColor=CV_RGB(rand()&255,rand()&255,rand()&255);
- //externalColor=CV_RGB(rand()&255,rand()&255,rand()&255);
- CvRect r = ((CvContour *)pcontour)->rect;
- if(r.height * r.width < 800)
- {
- holeColor=CV_RGB(0,0,0);
- externalColor=CV_RGB(0,0,0);
- cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
- }
- else
- {
- //取得轮廓面积
- double contArea = fabs(cvContourArea(pcontour,CV_WHOLE_SEQ));
- //取得轮廓长度
- double contLenth = cvArcLength(pcontour,CV_WHOLE_SEQ,-1);
- // 圆形度
- double contcircularity = contLenth * contLenth / contArea;
- double pxl =Eccentricity(temp);
- cout<<"面积为:"<<contArea<<endl;
- cout<<"周长为:"<<contLenth<<endl;
- cout<<"圆形度为:"<<contcircularity<<endl;
- holeColor=CV_RGB(255,255,255);
- externalColor=CV_RGB(255,255,255);
- cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
- }
- }
- //IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
- //cvDilate(pContourImg,pContourImg, element,9);
- return pContourImg;
- }
- double Eccentricity(IplImage *src)//偏心率
- {
- Position pos[4];
- int width = src->width;
- int height = src->height;
- int i,j;
- for(i = 0; i < height; i++)
- {
- for(j = 0; j < width; j++)
- {
- int pixel = (int)cvGet2D(src,i,j).val[0];
- if(pixel != 0)
- {
- pos[0].x = j;
- pos[0].y = i;//
- goto s;
- }
- }
- }
- s:
- for(i = height – 1; i >= 0; i–)
- {
- for(j = 0; j < width ; j++)
- {
- int pixel = (int)cvGet2D(src,i,j).val[0];
- if(pixel != 0)
- {
- pos[1].x = j;
- pos[1].y = i;//
- goto w;
- }
- }
- }
- w:
- for(i = 0 ; i < width ; i++)
- {
- for(j = 0;j < height; j++)
- {
- int pixel = (int)cvGet2D(src,j,i).val[0];
- if(pixel != 0)
- {
- pos[2].x = j;//
- pos[2].y = i;
- goto e;
- }
- }
- }
- e:
- for(i = width – 1; i >= 0; i–)
- {
- for(j = 0 ; j < height ; j++)
- {
- int pixel = (int)cvGet2D(src,j,i).val[0];
- if(pixel != 0)
- {
- pos[3].x = j;//
- pos[3].y = i;
- goto f;
- }
除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自OpenCV提取轮廓(去掉面积小的轮廓)