轮廓处理之三

上文目的为了求的运动物体的位置信息,但是在寻找轮廓时,发现轮廓并非我想要的轮廓发现了mode变量的影响。现在继续前面任务对某一图像来操作看看会有什么样的结果。

突然发现,主体图像的边缘出现了很多干扰的小点点。我该如何处理这些问题呢?

处理上述问题。

方案一:面积与目标面积相近的轮廓作为处理对象。

方案二:借助图像腐蚀、膨胀的办法去掉周边的小毛刺。关于腐蚀与膨胀的处理参见潜墨的文章(http://blog.csdn.net/poem_qianmo/article/details/23710721)。

腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图更小的高亮区域。

//By pengjc2001 (http://blog.csdn.net/pengjc2001)
#include <opencv2/opencv.hpp>
#include <stdlib.h>
#include "imgproc.hpp"
#include "cxcore.h"   
#include "cv.h"   
#include "highgui.h" 

double area = 0;
double perimeter = 0;
double position_x = 0;
double position_y = 0;


IplImage *colorImg = NULL;  //载入的图像
IplImage *grayImg = NULL;  //灰度图像
IplImage *binaryImg = NULL;  //二值图像
IplImage *edgeImg = NULL; //边缘
IplImage *erodeImg = NULL; //腐蚀后的二值图
IplImage *dilateImg = NULL; //膨胀后的二值图

const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsGrayTitle = "灰度图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsBinaryTitle = "二值图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsErodeTitle = "腐蚀后的二值图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsDilateTitle = "膨胀后的二值图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsOutLineTitle = "轮廓图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsErodeOutLineTitle = "腐蚀后的轮廓图(http://blog.csdn.net/pengjc2001)";
const char *pstrWindowsDilateOutLineTitle = "膨胀后的轮廓图(http://blog.csdn.net/pengjc2001)";


void Draw_Contours(IplImage *Img, const char *Title)
{
	CvMemStorage *pcvMStorage = cvCreateMemStorage();
	CvSeq *pcvSeq = NULL;
	cvFindContours(Img, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));

	// 画轮廓图
	IplImage *pOutlineImage = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 3);
	int nLevels = 3;
	// 填充成白色
	cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED);
	cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255, 0, 0), CV_RGB(0, 0, 0), nLevels, 1);
	// 显示轮廓图
	cvNamedWindow(Title, CV_WINDOW_AUTOSIZE);
	cvShowImage(Title, pOutlineImage);

	CvSeq *pcvSeqInner = NULL;
	int inner = 0;
	int external = 0;
	area = cvContourArea(pcvSeq);
	perimeter = cvArcLength(pcvSeq);


	for (; pcvSeq != NULL; pcvSeq = pcvSeq->h_next)
	{
		external++;
		area = cvContourArea(pcvSeq);
		perimeter = cvArcLength(pcvSeq);

		CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
		cvMoments(pcvSeq, moments, 1);
		double moment10 = cvGetSpatialMoment(moments, 1, 0);
		double moment01 = cvGetSpatialMoment(moments, 0, 1);
		area = cvGetCentralMoment(moments, 0, 0);
		position_x = moment10 / area;
		position_y = moment01 / area;

		printf("area:%f\t perimeter:%f\n", area, perimeter);
		printf("position_x: %f\t position_y: %f\t ", position_x, position_y);
		printf("external:%d\t inner = %d\t h_next\n", external, inner);
		for (pcvSeqInner = pcvSeq->v_next; pcvSeqInner != NULL; pcvSeqInner = pcvSeqInner->h_next)
		{
			inner++;
			double area = cvContourArea(pcvSeqInner);
			double perimeter = cvArcLength(pcvSeqInner);

			CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
			cvMoments(pcvSeqInner, moments, 1);
			double moment10 = cvGetSpatialMoment(moments, 1, 0);
			double moment01 = cvGetSpatialMoment(moments, 0, 1);
			area = cvGetCentralMoment(moments, 0, 0);
			position_x = moment10 / area;
			position_y = moment01 / area;

			printf("area:%f\t perimeter:%f\t", area, perimeter);
			printf("position_x: %f\t position_y: %f\t \n", position_x, position_y);
			printf("external:%d\t inner = %d\t \n", external, inner);

		}

	}

	cvWaitKey(10);

	cvReleaseMemStorage(&pcvMStorage);
	cvReleaseImage(&pOutlineImage);

}

int main(int argc, char** argv)
{


	colorImg = cvLoadImage("E:\\Visual Studio 2013\\Projects\\position_area2\\image1.jpg");


	// 显示原图
	cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsSrcTitle, colorImg);


	// 转为灰度图
	grayImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
	cvCvtColor(colorImg, grayImg, CV_BGR2GRAY);
	cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsGrayTitle, grayImg);

	// 转为二值图
	binaryImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
	cvThreshold(grayImg, binaryImg, 250, 255, CV_THRESH_BINARY);

	cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsBinaryTitle, binaryImg);

	IplConvKernel *element = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT);

	// 腐蚀操作
	erodeImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
	cvErode(binaryImg, erodeImg, element, 2);
	cvNamedWindow(pstrWindowsErodeTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsErodeTitle, erodeImg);

	// 膨胀操作
	dilateImg = cvCreateImage(cvGetSize(colorImg), IPL_DEPTH_8U, 1);
	cvDilate(binaryImg, dilateImg, element, 1);
	cvNamedWindow(pstrWindowsDilateTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsDilateTitle, dilateImg);


	Draw_Contours(binaryImg, pstrWindowsOutLineTitle);
	Draw_Contours(erodeImg, pstrWindowsErodeOutLineTitle);
	Draw_Contours(dilateImg, pstrWindowsDilateOutLineTitle);

	cvWaitKey(0);



	cvDestroyWindow(pstrWindowsSrcTitle);
	cvDestroyWindow(pstrWindowsOutLineTitle);
	cvDestroyWindow(pstrWindowsGrayTitle);
	cvDestroyWindow(pstrWindowsBinaryTitle);
	
	cvReleaseImage(&colorImg);
	cvReleaseImage(&grayImg);
	cvReleaseImage(&binaryImg);
	cvReleaseImage(&erodeImg);
	cvReleaseImage(&dilateImg);

	return 0;

}


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值