1. 程式人生 > >opencv中獲取任意方向的ROI

opencv中獲取任意方向的ROI

/ GetSpecifiedDirectionROI.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;

//計算距離

double DistanceOfPoints(const CvPoint &p1,const CvPoint &p2)
{
return sqrt(double (p1.y-p2.y)*(p1.y-p2.y)+(p1.x-p2.x)*(p1.x-p2.x));

}

// 計算角度

 double GetAngle(const CvPoint &p1,const CvPoint &p2)
{
if(p2.x==p1.x)
return CV_PI/2;
return atan(double (p2.y-p1.y)/(p2.x-p1.x));

}

//旋轉變換

bool TransformP2P(const CvPoint &in,CvPoint &out,double angle,const CvPoint &start_p)
{
CvPoint p=cvPoint(in.x-start_p.x,in.y-start_p.y);

double x = p.x * cos(angle) - p.y * sin(angle) ;  //angle 逆時針旋轉,四捨五入

double y = p.y * cos(angle) + p.x * sin(angle) ;

out.x= x + start_p.x;

out.y= y + start_p.y; 

if(out.x!=-1 && out.y!=-1)
return true;
return false;

}

//任意方向ROI抓取

bool GetSepDircROI(IplImage *src,IplImage *out,const CvPoint &start_p,const CvPoint &end_p,const int &rect_sw)
{
if(src == NULL ||end_p.x>src->width ||end_p.y>src->height)
return false;


double angle = 0; //矩形與X軸的夾角
if(end_p.x==start_p.x && end_p.y==start_p.y)
{
out=src;
}
else 
{
CvPoint pt1=start_p;
CvPoint pt2=end_p;
if(pt1.x>pt2.x || (pt1.x==pt2.x && pt2.y<pt1.y))
{
pt1=end_p;
pt2=start_p;

}

//Get angle from two points
angle = GetAngle(pt1,pt2);
//cout<<angle<<endl;
//get the coordinate of image point.

double rect_len=DistanceOfPoints(pt1,pt2);

//get the horizontal rect and transform to the real coordinate.
vector<CvPoint> vecp;

CvPoint ptTf;

for(int j=0;j<rect_sw*2;j++)
{
for(int i=0;i<rect_len;i++)
{

bool flag=TransformP2P(cvPoint(pt1.x+i,pt1.y-rect_sw+j),ptTf,angle,pt1);
if(flag)
{
vecp.push_back(ptTf);
}

}

}

uchar *data=(uchar *)out->imageData;
uchar *data2=(uchar *)src->imageData;

int step=src->widthStep/sizeof(uchar); 

for(int i=0;i<vecp.size();i++)
{
data[vecp[i].y*step+vecp[i].x] =data2[vecp[i].y*step+vecp[i].x]; 
}

}
return true;

}

//主函式

int _tmain(int argc, _TCHAR* argv[])
{
IplImage *img=cvLoadImage("1.jpg",0);
//cout<<img->width<<" , "<<img->height<<endl;
IplImage *out=cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
cvZero(out);
cvNamedWindow("src");

cvShowImage("src",img);

//測試用例

CvPoint p1=cvPoint(300,300);
for(int i=-18;i<19;i++)
{
CvPoint p2=cvPoint(300+250*cos(CV_PI*i/18),300+250*sin(CV_PI*i/18));
GetSepDircROI(img,out,p1,p2,10);
}
cvSmooth(out,out,CV_MEDIAN,3,3);
cvNamedWindow("out");
cvShowImage("out",out);
cvWaitKey(0);
return 0;
}