opencv 入门之数米粒:给出一幅米粒图数出图中米粒数目以及最大米粒位置。在原图上画出最大米粒的位置。使用 otsu、迭代和平均灰度进行二值分割。
声明:
本次实验采用 opencv 版本为 opencv1.0。
编程软件为 vc6.
- #include "cv.h"#include "highgui.h"#include#includeusing namespace std;
- int aver(IplImage * inputGrayImg) //平均灰度{uchar *data= (uchar *)inputGrayImg->imageData;int wp = inputGrayImg->widthStep;int i,j;int sum=0;for( i = 0; i < inputGrayImg->height; i++){for(j = 0; j < inputGrayImg->width; j++){sum = sum + data[i * wp + j];}}//获得所有灰度的和sumreturn int(sum*1.0/(inputGrayImg->height*inputGrayImg->width)+0.5);}int diedai(IplImage *inputGrayImg,int a){int threshold = 0;int newThreshold = a;while(threshold != newThreshold){int p=1,q=1;int sum1=0,sum2=0;uchar *data= (uchar *)inputGrayImg->imageData;int wp = inputGrayImg->widthStep;int i,j;for( i = 0; i < inputGrayImg->height; i++){for(j = 0; j < inputGrayImg->width; j++){if(data[i * wp + j] {sum1+=data[i * wp + j];p++;}else{sum2+=data[i * wp + j];q++;}}}int avg1=int(sum1/p);int avg2=int(sum2/q);threshold = newThreshold;newThreshold = (avg1+avg2)/2;}return threshold;}int otsu(IplImage *inputGrayImg,int u){int hui[256]={0};float g[256];uchar *data= (uchar *)inputGrayImg->imageData;int wp = inputGrayImg->widthStep;int i,j;for( i = 0; i < inputGrayImg->height; i++){for(j = 0; j < inputGrayImg->width; j++){hui[data[i * wp + j]]+=1;}}int sum=inputGrayImg->height*inputGrayImg->width;for(i=0;i<256;i++){int sum1=1,sum2=1;int hui1=1,hui2=1;for(j=0;j {sum1+=hui[j];hui1+=hui[j]*j;}for(j=i;j<256;j++){sum2+=hui[j];hui2+=hui[j]*j;}float w0,w1;int u0,u1;w0=sum1*1.0/sum;w1=sum2*1.0/sum;u0=int(hui1/sum1);u1=int(hui2/sum2);g[i]=w0 * (u0 - u) * (u0 - u) + w1 * (u1 - u) * (u1 - u);}int max=0;for(i=1;i<256;++i){if(g[max] max=i;}return max;}void main(){int averyuzhi,diedaiyuzhi,otsuyuzhi;IplImage *image=cvLoadImage("D:\\shumili\\rice.jpg",0);IplImage *image1=cvLoadImage("D:\\shumili\\rice.jpg",1);if(image==NULL){printf("无法读取图像数据!\n");return;//不作任何操作,就不会执行后面的程序了}IplImage *backImg=cvCreateImage(cvSize(image->width,image->height),8,1);IplImage *backRImg=cvCreateImage(cvSize(image->width,image->height),8,1);IplImage *cutImg=cvCreateImage(cvSize(image->width,image->height),8,1);IplImage *beijing=cvCreateImage(cvSize(image->width,image->height),8,3);uchar *data= (uchar *)beijing->imageData;int wp = beijing->widthStep;for(int i = 0; i < beijing->height; i++){for(int j = 0; j < beijing->width; j++){data[i * wp + 3 * j]=0;data[i * wp + 3 * j + 1]=0;data[i * wp + 3 * j + 2]=0;}}cvNamedWindow("图像显示",CV_WINDOW_AUTOSIZE);cvShowImage("图像显示",image1);//创建窗口展示图像*/// cvSaveImage("D:\\saveImage.jpg",image);IplConvKernel* element=cvCreateStructuringElementEx(4,4,1,1,CV_SHAPE_ELLIPSE,0);//形态学结构指针[创建结构元素,4列4行,椭圆形】cvErode(image,backImg,element,5);//腐蚀cvDilate(backImg,backImg,element,5);//膨胀cvNamedWindow("背景图像显示",CV_WINDOW_AUTOSIZE);cvShowImage("背景图像显示",backImg);//创建窗口展示图像cvSub(image,backImg,backRImg,0);cvNamedWindow("去背景图像显示",CV_WINDOW_AUTOSIZE);cvShowImage("去背景图像显示",backRImg);//创建窗口展示图像averyuzhi=aver(backRImg);//33diedaiyuzhi=diedai(backRImg,averyuzhi);//49otsuyuzhi=otsu(backRImg,averyuzhi);//58printf("%d\n",averyuzhi);printf("%d\n",diedaiyuzhi);printf("%d\n",otsuyuzhi);// cvThreshold(backRImg,cutImg,averyuzhi,255,CV_THRESH_BINARY);cvThreshold(backRImg,cutImg,diedaiyuzhi,255,CV_THRESH_BINARY);// cvThreshold(backRImg,cutImg,otsuyuzhi,255,CV_THRESH_BINARY);//cutImg是分割图像cvErode(cutImg,cutImg,element,1);//腐蚀cvDilate(cutImg,cutImg,element,1);//膨胀//经过一次腐蚀膨胀去掉图像中的噪声cvNamedWindow("otsu分割图像显示",CV_WINDOW_AUTOSIZE);cvShowImage("otsu分割图像显示",cutImg);//创建窗口展示图像CvMemStorage* stor=cvCreateMemStorage(0);CvSeq *cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);CvSeq *cont1=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);int numberOfObject=cvFindContours(cutImg,stor,&cont,sizeof(CvContour),CV_RETR_TREE);int numberOfObject1=cvFindContours(cutImg,stor,&cont1,sizeof(CvContour),CV_RETR_TREE);//findcontours找轮廓printf("米粒个数为 %d\n",numberOfObject);float tmpArea=0;float tmpLength=0;int x1,y1;for (;cont != NULL;cont=cont->h_next){CvRect rect=cvBoundingRect(cont,0);float tmpArea1=fabs(cvContourArea(cont,CV_WHOLE_SEQ));float tmpLength1=cvArcLength(cont);if(tmpArea {tmpArea=tmpArea1;tmpLength=tmpLength1;x1=rect.x;y1=rect.y;}cvDrawContours(beijing,cont,CV_RGB(255,255,255),CV_RGB(255,0,0),0,1,8,cvPoint(1,1));//在图像上绘制轮廓.}for (;cont1 != NULL;cont1=cont1->h_next){CvRect rect=cvBoundingRect(cont1,0);float tmpArea1=fabs(cvContourArea(cont1,CV_WHOLE_SEQ));if(rect.x==x1&&y1==rect.y&&tmpArea1==tmpArea)cvDrawContours(beijing,cont1,CV_RGB(255,0,0),CV_RGB(255,0,0),0,1,8,cvPoint(1,1));//在图像上绘制轮廓.}printf("面积为:%f\n周长为:%f\n",tmpArea,tmpLength);printf("最大面积位置坐标为:%d %d\n",x1,y1);cvNamedWindow("图像显示",CV_WINDOW_AUTOSIZE);cvShowImage("图像显示",beijing);//创建窗口展示图像cvWaitKey(0);//一直等待按键没有这句的话图像不能正常显示cvReleaseImage(&image);//释放图像内存cvDestroyWindow("图像显示");//销毁窗口资源cvDestroyWindow("背景图像显示");//销毁窗口资源cvDestroyWindow("去背景图像显示");//销毁窗口资源cvDestroyWindow("otsu分割图像显示");//销毁窗口资源//读取和显示完图像之后,要及时释放所占的内存资源.}
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/04-17/20575421.html