尝试匹配的轮廓,CV Mat和Iplimage的麻烦

时间:2014-12-11 08:50:42

标签: c++ opencv rotation iplimage opencv-mat

我正在进行匹配轮廓测试。

这里我使用名为“refshape.bmp”的图像 (链接:https://www.dropbox.com/s/06hrjji49uyid4w/refshape.bmp?dl=0) 图像称为“2.bmp” (链接:https://www.dropbox.com/s/5t73mvbdfbtqvs1/2.BMP?dl=0

进行此测试。

此代码如下: 我有两部分代码 第1部分:旋转“refshape.bmp”图像 第2部分:使用红线匹配轮廓。 (单独的部分可以成功运作!) 但是我在CV Mat和IplImage之间转换时遇到了 问题。

有溢出警告: 链接:www.dropbox.com/s/mne4u3va94svx8y/%E6%93%B7%E5%8F%96.JPG? DL = 0

第一部分有一个CV垫(图像)“dst” 然后我将它转换为IplImage:“IplImage * reference =©” “IplImage * reference =©”

#include <stdlib.h>
#include<iostream>
#include "time.h"
#include "highgui.h"
#include "cv.h"

using namespace std;

int comp(const void *p,const void *q)
{
   return (*(int *)p - *(int *)q);
}




int main()

{   int i =0;
    cv::Mat src = cv::imread("refshape.bmp", CV_LOAD_IMAGE_UNCHANGED);
    int angle = -i;

    // get rotation matrix for rotating the image around its center
    cv::Point2f center(src.cols/2.0, src.rows/2.0);
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
    // determine bounding rectangle
    cv::Rect bbox = cv::RotatedRect(center,src.size(), angle).boundingRect();
    // adjust transformation matrix
    rot.at<double>(0,2) += bbox.width/2.0 - center.x;
    rot.at<double>(1,2) += bbox.height/2.0 - center.y;

    cv::Mat dst;
    cv::warpAffine(src, dst, rot, bbox.size());
	IplImage copy = dst;



	IplImage* input = NULL;
	IplImage* input_canny = NULL;
	IplImage* input_final = NULL;
	//IplImage* reference = NULL;
	IplImage* input_gray = NULL;
	IplImage* reference_gray = NULL;
	IplImage* find_contour = NULL;

	IplImage* reference= &copy;

	//圖像的尺寸的寬度大小
	int x_min = 229;               
	int x_max = 0;

	//圖像尺寸的高度大小
	int y_min = 111;
	int y_max = 0;
	
	int n = 0;  

	//reference = cvLoadImage("refshape.bmp",1);//讀取圖檔
	input = cvLoadImage("2.bmp",1);//讀取圖檔

	input_canny=cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,1);//canny灰階

	input_final=cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,3);//canny RGB

	cvCvtColor(input, input_canny, CV_BGR2GRAY);//轉灰階圖
	
	cvCanny(input_canny,input_canny,80,150,3);// canny edge

	cvCvtColor(input_canny, input_final, CV_GRAY2BGR);// canny 灰階轉RGB
	

	reference_gray = cvCreateImage(cvSize(reference->width, reference->height),  IPL_DEPTH_8U,1);
	input_gray = cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,1);

	CvMemStorage* storage = cvCreateMemStorage(0);
	CvSeq *contour = 0;

	//cvFindContours只能使用灰階影像,故須先轉成灰階
	cvCvtColor(reference, reference_gray, CV_BGR2GRAY);

	cvFindContours(reference_gray, storage, &contour, sizeof(CvContour), CV_RETR_LIST , CV_CHAIN_APPROX_NONE, cvPoint(0,0));

	//用來存放點的位置矩陣
	CvPoint* PointArray[50000]={0};



	//以下是將每一層的每個點的位置座標,存到PointArray裡,並且找出所有sample點x,y軸的最大最小值
	for( CvSeq* c = contour; c != NULL; c=c->h_next )
    {
        for( int i = 0; i<c->total; i++ )
		{
			
			PointArray[n] = CV_GET_SEQ_ELEM( CvPoint, c, i );

			if(PointArray[n]->x < x_min)
			{
				x_min = PointArray[n]->x;
			}
			
			if(PointArray[n]->y < y_min)
			{
				y_min = PointArray[n]->y;
			}

			if(PointArray[n]->x > x_max)
			{
				x_max = PointArray[n]->x;
			}

			if(PointArray[n]->y > y_max)
			{
				y_max = PointArray[n]->y;
			}

			n+=1;
		}
    }
    

	CvScalar s,t;
	int match_x;
	int match_y;

// Contour matching

	int x;
	int y;
	int matchcount=0;
	int maxcount=0;

	for(int i=0;i<780;i++)
	{
		for(int j=0;j<630;j++)
		{ 
			matchcount=0;
			for(int a = 0; a < n; a++)
			{
				s = cvGet2D(input_final, PointArray[a]->y -y_min+j, PointArray[a]->x -x_min+i);
				t = cvGet2D(reference,PointArray[a]->y,PointArray[a]->x);
				        
				if(s.val[0]==255 && t.val[0]==255)
					matchcount++;
			}
			if(matchcount>maxcount)
			{
				maxcount=matchcount;
				match_x =i ;
				match_y =j ;
			}
		}
	}
	     
	system("pause");
	//當找到match數最多的位置時,設定要畫出的顏色後,將這些點標上顏色
	for(int a = 0; a < n; a++)
	{
		t.val[0] = 0;
		t.val[1] = 0;
		t.val[2] = 255;

		//標上顏色
		cvSet2D(input_final, PointArray[a]->y-y_min+match_y, PointArray[a]->x-x_min+match_x, t);
	}

	system("pause");
	cvNamedWindow("reference_gray",1);
	cvNamedWindow("reference",1);
	cvNamedWindow("input",1);
	cvShowImage("reference_gray",reference_gray);
	cvShowImage("reference",reference);
	cvShowImage("input",input_final);
	
	cvSaveImage("result.bmp",input_final);
	system("pause");
	cvWaitKey(0);

    return 0;
}

有单独的代码: 旋转:

#include "opencv2/opencv.hpp"
#include <sstream>

int main()
{	for (int i=0;i<361;i++)
{
    cv::Mat src = cv::imread("refshape.bmp", CV_LOAD_IMAGE_UNCHANGED);
    int angle = -i;

    // get rotation matrix for rotating the image around its center
    cv::Point2f center(src.cols/2.0, src.rows/2.0);
    cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
    // determine bounding rectangle
    cv::Rect bbox = cv::RotatedRect(center,src.size(), angle).boundingRect();
    // adjust transformation matrix
    rot.at<double>(0,2) += bbox.width/2.0 - center.x;
    rot.at<double>(1,2) += bbox.height/2.0 - center.y;

    cv::Mat dst;
    cv::warpAffine(src, dst, rot, bbox.size());

    std::ostringstream name;
    name << "rotated_im_" << i << ".png";
    cv::imwrite(name.str(), dst);
}
    return 0;
}

匹配轮廓代码:

#include <stdlib.h>
#include<iostream>
#include "time.h"
#include "highgui.h"
#include "cv.h"

using namespace std;

int comp(const void *p,const void *q)
{
   return (*(int *)p - *(int *)q);
}

int main()
{
	IplImage* input = NULL;
	IplImage* input_canny = NULL;
	IplImage* input_final = NULL;
	IplImage* reference = NULL;
	IplImage* input_gray = NULL;
	IplImage* reference_gray = NULL;
	IplImage* find_contour = NULL;

	//圖像的尺寸的寬度大小
	int x_min = 229;               
	int x_max = 0;

	//圖像尺寸的高度大小
	int y_min = 111;
	int y_max = 0;
	
	int n = 0;  

	reference = cvLoadImage("refshape.bmp",1);//讀取圖檔
	input = cvLoadImage("2.bmp",1);//讀取圖檔

	input_canny=cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,1);//canny灰階

	input_final=cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,3);//canny RGB

	cvCvtColor(input, input_canny, CV_BGR2GRAY);//轉灰階圖
	
	cvCanny(input_canny,input_canny,80,150,3);// canny edge

	cvCvtColor(input_canny, input_final, CV_GRAY2BGR);// canny 灰階轉RGB
	

	reference_gray = cvCreateImage(cvSize(reference->width, reference->height),  IPL_DEPTH_8U,1);
	input_gray = cvCreateImage(cvSize(input->width, input->height),  IPL_DEPTH_8U,1);

	CvMemStorage* storage = cvCreateMemStorage(0);
	CvSeq *contour = 0;

	//cvFindContours只能使用灰階影像,故須先轉成灰階
	cvCvtColor(reference, reference_gray, CV_BGR2GRAY);

	cvFindContours(reference_gray, storage, &contour, sizeof(CvContour), CV_RETR_LIST , CV_CHAIN_APPROX_NONE, cvPoint(0,0));

	//用來存放點的位置矩陣
	CvPoint* PointArray[5000]={0};



	//以下是將每一層的每個點的位置座標,存到PointArray裡,並且找出所有sample點x,y軸的最大最小值
	for( CvSeq* c = contour; c != NULL; c=c->h_next )
    {
        for( int i = 0; i<c->total; i++ )
		{
			
			PointArray[n] = CV_GET_SEQ_ELEM( CvPoint, c, i );

			if(PointArray[n]->x < x_min)
			{
				x_min = PointArray[n]->x;
			}
			
			if(PointArray[n]->y < y_min)
			{
				y_min = PointArray[n]->y;
			}

			if(PointArray[n]->x > x_max)
			{
				x_max = PointArray[n]->x;
			}

			if(PointArray[n]->y > y_max)
			{
				y_max = PointArray[n]->y;
			}

			n+=1;
		}
    }
    

	CvScalar s,t;
	int match_x;
	int match_y;

// Contour matching

	int x;
	int y;
	int matchcount=0;
	int maxcount=0;

	for(int i=0;i<780;i++)
	{
		for(int j=0;j<630;j++)
		{ 
			matchcount=0;
			for(int a = 0; a < n; a++)
			{
				s = cvGet2D(input_final, PointArray[a]->y -y_min+j, PointArray[a]->x -x_min+i);
				t = cvGet2D(reference,PointArray[a]->y,PointArray[a]->x);
				        
				if(s.val[0]==255 && t.val[0]==255)
					matchcount++;
			}
			if(matchcount>maxcount)
			{
				maxcount=matchcount;
				match_x =i ;
				match_y =j ;
			}
		}
	}
	     
	system("pause");
	//當找到match數最多的位置時,設定要畫出的顏色後,將這些點標上顏色
	for(int a = 0; a < n; a++)
	{
		t.val[0] = 0;
		t.val[1] = 0;
		t.val[2] = 255;

		//標上顏色
		cvSet2D(input_final, PointArray[a]->y-y_min+match_y, PointArray[a]->x-x_min+match_x, t);
	}

	system("pause");
	cvNamedWindow("reference_gray",1);
	cvNamedWindow("reference",1);
	cvNamedWindow("input",1);
	cvShowImage("reference_gray",reference_gray);
	cvShowImage("reference",reference);
	cvShowImage("input",input_final);
	
	cvSaveImage("result.bmp",input_final);
	system("pause");
	cvWaitKey(0);
}

0 个答案:

没有答案