已经可以显示图片的最大连通域,并且用cvDrawContors画出的轮廓线为一条但是输出cvFindContors的返回值是一个很长的定值,我觉得如果正确提取轮廓的话应该返回1才对,求大神解答 ^ ^
#include <cv.h>
#include <highgui.h>
#include <vector>
#include <algorithm>
using namespace std;
int tx=0, ty=0, x=0, y=0;
IplImage* red(IplImage* H, IplImage* S, IplImage* V, IplImage* imgin)
{
int x1, y1;
for (y1 = 0; y1<H->height; y1++)
{
uchar* ptr1 = (uchar*)imgin->imageData + y1*imgin->width;//获得灰度值数据指针
for (x1 = 0; x1<H->width; x1++)
{
double h = cvGetReal2D(H, y1, x1);
double s = cvGetReal2D(S, y1, x1);
double v = cvGetReal2D(V, y1, x1);
if (((h>0 && h<10) || (h>156 && h<180)) && (s>100 && s<255) && (v>46 && v < 255))
{
ptr1[x1] = 0;
}
else ptr1[x1] = 255;
}
}
return imgin;
}
int main()
{
IplImage *img;
CvCapture *capture;
capture = cvCreateCameraCapture(0);
assert(capture != NULL);
cvNamedWindow("yuantu", CV_WINDOW_AUTOSIZE);
cvNamedWindow("lunkuo", CV_WINDOW_AUTOSIZE);
while (1)
{
img = cvQueryFrame(capture);
if (!img) break;
char c = cvWaitKey(33);
IplImage *img1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
IplImage *img2 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
IplImage *img3 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
IplImage *img4 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *img5 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *img6 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *img7 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *img8 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *img9 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *dst = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *H = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *S = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *V = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
CvSeq* contours = 0;
CvMemStorage* storage = cvCreateMemStorage(0);
int m = 0;
cvSmooth(img, img1, CV_GAUSSIAN);
cvSmooth(img1, img2, CV_MEDIAN);
cvCvtColor(img2, img3, CV_BGR2HSV);
cvCvtPixToPlane(img3, H, S, V, 0);
cvCvtColor(img2, img4, CV_BGR2GRAY);
img5 = red(H, S, V, img4);
cvDilate(img5, img6);
cvErode(img6, img7);
cvThreshold(img7,img8, 0.0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);//OTSU二值化
IplConvKernel *element = cvCreateStructuringElementEx(5, 5, 0, 0, CV_SHAPE_ELLIPSE);
cvMorphologyEx(img8, img8, NULL, element, CV_MOP_OPEN);//开运算,去除比结构元素小的点
cvReleaseStructuringElement(&element);
int w, h;
CvSize sz = cvGetSize(img8);
int color1 = 254;//不对0计数,不可能为255,所以254
for (w = 0; w<sz.width; w++)
{
for (h = 0; h<sz.height; h++)
{
if (color1 > 0)
{
if (CV_IMAGE_ELEM(img8, unsigned char, h, w) ==0)
{
//把连通域标记上颜色
cvFloodFill(img8, cvPoint(w, h), CV_RGB(color1, color1, color1));
color1--;
}
}
}
}
int colorsum[255] = { 0 };
for (w = 0; w<sz.width; w++)
{
for (h = 0; h<sz.height; h++)
{
if (CV_IMAGE_ELEM(img8, unsigned char, h, w) > 0)
{
colorsum[CV_IMAGE_ELEM(img8, unsigned char, h, w)]++;//统计每种颜色的数量
}
}
}
vector<int> v1(colorsum, colorsum + 255);//用数组初始化vector
//求出最多数量的染色,注意max_element的使用方法
int maxcolorsum = max_element(v1.begin(), v1.end()) - v1.begin();
for (w = 0; w<sz.width; w++)
{
for (h = 0; h<sz.height; h++)
{
if (CV_IMAGE_ELEM(img8, unsigned char, h, w) == maxcolorsum)
{
CV_IMAGE_ELEM(img8, unsigned char, h, w) = 255;
}
else
{
CV_IMAGE_ELEM(img8, unsigned char, h, w) = 0;
}
}
}
int contour_num = cvFindContours(img8, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
cvDrawContours(img8,contours,cvScalar(100),cvScalar(100),1);
cvShowImage("yuantu", img);
cvShowImage("lunkuo",img8);
if (c == 27)
{
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvReleaseImage(&img4);
cvReleaseImage(&img5);
cvReleaseImage(&img6);
cvReleaseImage(&img7);
cvReleaseImage(&img8);
cvReleaseImage(&img9);
cvReleaseImage(&dst);
cvReleaseImage(&H);
cvReleaseImage(&S);
cvReleaseImage(&V);
cvReleaseMemStorage(&storage);
break;
}
}
cvReleaseImage(&img);
cvDestroyWindow("yuantu");
cvDestroyWindow("lunkuo");
}