マッチング輪郭テストを行っています。
ここでは、「refshape.bmp」という画像 (リンク: https://www.dropbox.com/s/06hrjji49uyid4w/refshape.bmp?dl=0 ) と「2.bmp」という画像 (リンク: https:// www.dropbox.com/s/5t73mvbdfbtqvs1/2.BMP?dl=0 )
このテストを行うには。
このコードは次のとおりです。このコードには 2 つの部分があります。パート 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= ©
//圖像的尺寸的寬度大小
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);
}