Opencv提取不规则ROI

这次第一次写博客,写的不太好,希望大家多多包涵,有错的地方也希望大家提出来~~

写博客的主要目的是让自己做一个总结,以此来孔固自己所学的东西,希望自己能一直努力下去,继续坚持!!!

前两天在halcon中看到一个sobel的例子,是关于提取公路上的交通标线。首先它创建了一个网格,以这个网格为模板进行不规则的ROI提取,然后进行sobel边缘检测,再经过膨胀,再提取不规则ROI提取,最后进行阈值处理即可把交通标线提取出来。这样说比较抽象,大家可以在下边看到这个算法实现过程中的图片,再结合文字会比较好理解一点。

但我把这个例程看完后,就在想,我能够用opencv来实现这个算法吗?我想应该会比较复杂一点,因为我自己本身也不太懂opencv,比较生疏,所以写的有点乱,以下代码因为经常从Mat和IplImage之间转换,比较繁琐,大家做的过程中始终用IplImage会比较简单,只不过我偏向于C++,有些函数想cvCopy必须要用IplImage,所以没办法了只能讲Mat转为IplImage

Opencv提取不规则ROI_第1张图片Opencv提取不规则ROI_第2张图片Opencv提取不规则ROI_第3张图片Opencv提取不规则ROI_第4张图片Opencv提取不规则ROI_第5张图片Opencv提取不规则ROI_第6张图片Opencv提取不规则ROI_第7张图片

#include 
#include 
#include 
#include 
using namespace cv;
using namespace std;

/*创建网格函数*/
void cvCreateGrid(Mat &src, Mat &dst, uchar x, uchar y, int witdh, int height, int span);
void createGrid(IplImage *img, uchar x, uchar y, int witdh, int height, int span, int line_width);

int main(){
	/*加载一张待处理图片*/
	IplImage *src = cvLoadImage("scene_00.png");
	Size rect = cvGetSize(src);

	/*创建一张与src一样大小的单通道图片mask*/
	IplImage* mask = cvCreateImage(rect, src->depth, CV_8UC1);

	/*创建一个网格,该网格用于以后的边缘提取*/
	createGrid(mask, 10, 130, 502, 350, 10,3);

	/*创建一张黑色的图片*/
	IplImage* img_stripGrid0 = cvCreateImage(rect, src->depth, src->nChannels);
	cvZero(img_stripGrid0);

	/*以mask作为模板提取不规则ROI*/
	cvCopy(src, img_stripGrid0, mask);

	/*用Canny算子进行边缘提取*/
	IplImage *img_stripGridCanny = cvCreateImage(rect, src->depth, src->nChannels);
	Mat img_stripGrid0_1 = cvarrToMat(img_stripGrid0);
	Mat img_stripGridCanny0 = cvarrToMat(img_stripGridCanny);
	Canny(img_stripGrid0_1, img_stripGridCanny0, 1000, 1000);


	/*对图片img_stripGridCanny0进行膨胀处理*/
	Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
	dilate(img_stripGridCanny0, img_stripGridCanny0, element, Point(-1, -1), 12);

	/*以图片img_stripGridCanny0作为模板再次提取不规则ROI*/
	IplImage *stripGrid = &IplImage(img_stripGridCanny0);
	IplImage *strip = cvCreateImage(rect, src->depth, src->nChannels);
	cvZero(strip);
	cvCopy(src, strip, stripGrid);

	/*阈值化处理,将公路的交通标线提取出来*/
	IplImage *bin = cvCreateImage(rect, src->depth, src->nChannels);
	cvThreshold(strip, bin, 190, 255, CV_THRESH_BINARY);

	namedWindow("src");
	cvShowImage("src", src);
	namedWindow("result");
	cvShowImage("result", bin);

	waitKey(0);	
	cvReleaseImage(&src);
	cvReleaseImage(&mask);
	cvReleaseImage(&img_stripGrid0);
	cvReleaseImage(&img_stripGridCanny);
	cvReleaseImage(&strip);
	cvReleaseImage(&bin);
	destroyWindow("src");
	destroyWindow("result");


	return 0;
}

void cvCreateGrid(Mat &src, Mat &dst, uchar x, uchar y, int witdh, int height,int span){
	int h = src.rows;
	int w = src.cols;
	Size size(w, h);
	dst = Mat::zeros(size, CV_8UC1);
	for (int i = x; i < x+witdh; i += span)
	{
		for (int j = y; j < y+height; j++)
		{
			dst.at(i, j) = 255;
		}
	}
	for (int j = y; j < y+height; j += span)
	{
		for (int i = x; i < x+witdh; i++)
		{
			dst.at(i, j) = 255;
		}
	}

}
/*
	创建网格函数
	* img:输出图像
	* x:起始x坐标
	* y:起始y坐标
	* witdh:网格宽度
	* heigh:网格高度
	* span:网格间隔
	* line_width:线条宽度
*/
void createGrid(IplImage *img, uchar x, uchar y, int witdh, int height, int span,int line_width){
	
	cvZero(img);
	for (int k = 0; k < line_width; k++)
	{
		for (int j = y+k; j < y + k + height; j++){
			uchar* ptr = (uchar*)(img->imageData + j*img->widthStep);
			for (int i = x+k; i imageData + j*img->widthStep);
			for (int i = x+k; i < x+k + witdh; i++){
				ptr[i] = 255;
			}
		}
	}
	
}


你可能感兴趣的:(Opencv提取不规则ROI)