日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

OpenCV提取轮廓(去掉面积小的轮廓)

發(fā)布時間:2023/11/27 生活经验 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV提取轮廓(去掉面积小的轮廓) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自:http://www.kaixuela.net/?p=23

?

#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);

??? // 創(chuàng)建結(jié)構(gòu)元素

??? IplConvKernel? *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);

??? //用該結(jié)構(gòu)對源圖象進行數(shù)學(xué)形態(tài)學(xué)的開操作后,估計背景亮度

??? cvErode(src,tmp,element,9);

??? //使用任意結(jié)構(gòu)元素腐蝕圖像

??? cvDilate(tmp,src_back, element,9);

??? //使用任意結(jié)構(gòu)元素膨脹圖像

}

?

?

IplImage *FindCountours(IplImage* src,IplImage *pContourImg)

{

??? CvMemStorage *storage = cvCreateMemStorage(0); //提取輪廓需要的儲存容量為默認(rèn)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; // 輪廓數(shù)量

??? //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;

??????????? }

?

??????? }

??? }

?

f:

??? int l_dis = abs(pos[0].y pos[1].y);

??? int s_dis = abs(pos[2].x pos[3].x);

??? int tmp_dis;

??? if(l_dis > s_dis)

??? {

??????? printf("偏心率:%f\n",l_dis*1.0/s_dis);

??? }

??? else

??? {

??????? tmp_dis = l_dis;

??????? l_dis = s_dis;

??????? s_dis = tmp_dis;

??????? printf("偏心率:%f\n",l_dis*1.0/s_dis);

??? }

?

??? return 0;

}

?

void Getprobability(IplImage *src)

{

??? memset(per,0,sizeof(per));

??? int width = src->width;

??? int height = src->height;

??? for(int i = 0; i < height; i++) {

??????? for(int j = 0; j < width; j++) {

??????????? per[(int)cvGet2D(src,i,j).val[0]]++;

??????? }

??? }

??? int PixlNum = width * height;

??? for(i = 0; i < 256; i++)

??????? per[i] = per[i] / PixlNum;

?

}

?

int GetThreshold(double *const prob)

{

??? int threshold = 0;

??? double maxf = 0;

??? for (int crrctThrshld = 1; crrctThrshld < 256 1; ++crrctThrshld) {

??????? double W0 = 0, W1 = 0, U0 = 0, U1 = 0;

??????? int i = 0;

??????? for (i = 0; i <= crrctThrshld; ++i) {?

??????????? U0 += i * prob[i];

??????????? W0 += prob[i];

??????? }

??? ??? for (; i < 256; ++i) {

??????????? U1 += i * prob[i];

??????????? W1 += prob[i];

??????? }

??????? if (W1 == 0 || W1 == 0)

??????????? continue;

??????? U0 /= W0;

??????? U1 /= W1;

??????? double D0 = 0, D1= 0;

??????? for (i = 0; i <= crrctThrshld; ++i)?

??????????? D0 += pow((i U0) * prob[i], 2.0);

??????? for (; i < 256; ++i)?

??????????? D1 += pow((i U1) * prob[i], 2.0);

??????? D0 /= W0;

??????? D1 /= W1;

??????? double Dw = pow(D0, 2.0) * W0 + pow(D1, 2.0) * W1;

??????? double Db = W0 * W1 * pow((U1 U0), 2.0);

??????? double f = Db / (Db + Dw);

??????? if (maxf < f) {

??????????? maxf = f;

??????????? threshold = crrctThrshld;

??????? }

??? }

??? return threshold;

}

?

void proBorder(IplImage *src) // 邊界的處理

{

??? int i,j;

??? int height = src->height;

??? int width = src->width;

?

??? int N = 100;

?

??? for(i = 0; i < N * width; i += width) // i表示向下走左上角

??? {

??????? for(j = 0; j < N ; j++)

??????? {

??? ??????? int index = i + j;

??????????? src->imageData[index] = (char)255;

??????? }

??? }

?

??? int NN = 150;

??? int sw = width * (height NN);// 左下角 三角形

??? int? t = 1;

??? for(i = sw; i < sw + NN * width; i += width,t++)

??? {

??????? for(j = 0; j < t; j++)

??????? {

??????????? int index = i + j;

??????????? src->imageData[index] = (char)255;

??????? }

??? }

?

??? int se = (height NN 1) * width; // 右下角

??? t = 0;

??? for(i = se; i < width * height ; i += width,t++)

??? {

??????? for(j = 0; j < t; j++)

??????? {

??????????? int index = i + j t;

??????????? src->imageData[index] = (char)255;

??????? }

??? }

?

??? int ne = width NN;?????????????????? // 右上角 三角形剪切

??? t = 0;

??? for(i = ne; i < NN * width; i +=width,t++)

??? {

??????? for(j = 0; j < NN t; j++)

??????? {

??????????? int index = i + j + t;

??????????? src->imageData[index] = (char)255;

??????? }

??? }

?

}

?

void Threshold(IplImage *src)

{

??? int width = src->width;

??? int height = src->height;

??? float minpixel = cvGet2D(src,0,0).val[0];

??? float maxpixel = cvGet2D(src,0,0).val[0];

??? CvScalar s;

??? for(int i = 0; i < height; i++){

??????? for(int j = 0; j < width; j++){

??????????? s = cvGet2D(src,i,j);

??????????? if(s.val[0] > maxpixel)

??? ??????????? maxpixel = s.val[0];

??????????? if(s.val[0] < minpixel)

??????????????? minpixel = s.val[0];

??????? }

??? }

??? float firstgrey = (maxpixel + minpixel) / 2;

??? printf("%f\n",firstgrey);

?

??? float lastgrey;

??? float sum1 = 0,sum2 = 0;

??? int num1 = 0,num2 = 0;

??? int result = 0;

??? while(1)

??? {

??????? result ++;

??????? for(i = 0; i < height; i++){

??????????? for(int j = 0; j < width; j++){

??????????????? s = cvGet2D(src,i,j);

??????????????? if(s.val[0] < firstgrey)

??????????????? {

??????????????????? sum1 += s.val[0];

??????????????????? num1++;

??????????????? }

??????????????? if(s.val[0] < firstgrey)

??????????????? {

??????????????????? sum2 += s.val[0];

??????????????????? num2++;

??????????????? }

??????????? }

??????? }

??????? lastgrey = (sum1/num1 + sum2/num2)/2;

?

??????? if((int)lastgrey == (int)firstgrey)

??????????? break;

??????? else

??????? {

??????????? firstgrey = lastgrey;

??????????? sum1 = sum2 = 0;

??????????? num1 = num2 = 0;

??????? }

??? }

?

??? lastgrey = (sum1/num1 + sum2/num2)/2;

??? printf("%f %d\n",firstgrey,result);

}

?

總結(jié)

以上是生活随笔為你收集整理的OpenCV提取轮廓(去掉面积小的轮廓)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

歡迎分享!

轉(zhuǎn)載請說明來源于"生活随笔",并保留原作者的名字。

本文地址:OpenCV提取轮廓(去掉面积小的轮廓)