opencv中获取任意方向的ROI

15 篇文章 2 订阅
/ 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;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值