先放代码
这版的代码有点错误,里面的指针分配了内存以后没有释放,有可能会造成内存泄漏
问题原因已经找到了,现在有点累,休息一下。。。
大概说一下吧,主要是因为越界的问题
比如说反变换到输入图像的时候,正确范围应该是(0,in.rows-1)而不是(0,in.rows)
果然,这一版的函数还是有bug,图像的平移参数只能是正整数。。。正在修改中。。。
而且函数接口太次,只能实现CV_8UC1类型的图像的仿射变换
准备改进一下,同时实现CV_32FC1类型的图像的变换
// affine.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
void imgaffine(cv::Mat in,cv::Mat out,cv::Mat matrix);
// 123.cpp : 定义控制台应用程序的入口点。
//
int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat a=imread("lena.bmp");
cv::cvtColor(a,a,CV_RGB2GRAY);
cv::Mat matrix(1,7,CV_32F);
float* data_t=matrix.ptr<float>(0);
data_t[0]=5;
data_t[1]=10;
data_t[2]=10;
data_t[3]=0.8;
data_t[4]=0.8;
data_t[5]=0;
data_t[6]=0;
float theta=data_t[0]*3.1415926/180;
int dx =data_t[1];
int dy =data_t[2];
float sx =data_t[3];
float sy =data_t[4];
int shx =data_t[5];
int shy =data_t[6];
int m1=a.rows;
int n1=a.cols;
float cx1,cy1;
cx1=(n1-1)/2.0;
cy1=(m1-1)/2.0;
cv::Mat tt1= cv::Mat(cv::Size(3,3), CV_32FC1);
cv::Mat tt2= cv::Mat(cv::Size(3,3), CV_32FC1);
cv::Mat tt3= cv::Mat(cv::Size(3,3), CV_32FC1);
cv::Mat tt4= cv::Mat(cv::Size(3,3), CV_32FC1);
tt1.at<float>(0,0)=cos(theta);
tt1.at<float>(0,1)=sin(theta);
tt1.at<float>(0,2)=0;
tt1.at<float>(1,0)=-sin(theta);
tt1.at<float>(1,1)=cos(theta);
tt1.at<float>(1,2)=0;
tt1.at<float>(2,0)=cx1-cx1*cos(theta)+cy1*sin(theta);
tt1.at<float>(2,1)=cy1-cx1*sin(theta)-cy1*cos(theta);
tt1.at<float>(2,2)=1;
tt2.at<float>(0,0)=1;
tt2.at<float>(0,1)=0;
tt2.at<float>(0,2)=0;
tt2.at<float>(1,0)=0;
tt2.at<float>(1,1)=1;
tt2.at<float>(1,2)=0;
tt2.at<float>(2,0)=dx;
tt2.at<float>(2,1)=dy;
tt2.at<float>(2,2)=1;
tt3.at<float>(0,0)=sx;
tt3.at<float>(0,1)=0;
tt3.at<float>(0,2)=0;
tt3.at<float>(1,0)=0;
tt3.at<float>(1,1)=sy;
tt3.at<float>(1,2)=0;
tt3.at<float>(2,0)=0;
tt3.at<float>(2,1)=0;
tt3.at<float>(2,2)=1;
tt4.at<float>(0,0)=1;
tt4.at<float>(0,1)=shy;
tt4.at<float>(0,2)=0;
tt4.at<float>(1,0)=shx;
tt4.at<float>(1,1)=1;
tt4.at<float>(1,2)=0;
tt4.at<float>(2,0)=0;
tt4.at<float>(2,1)=0;
tt4.at<float>(2,2)=1;
cv::Mat T= cv::Mat(cv::Size(3,3), CV_32FC1);
T=tt1*tt2*tt3*tt4;
cv::Mat TT=cv::Mat::zeros(2, 3, CV_32F);
TT.at<float>(0,0)=T.at<float>(0,0);
TT.at<float>(1,0)=T.at<float>(0,1);
TT.at<float>(0,1)=T.at<float>(1,0);
TT.at<float>(1,1)=T.at<float>(1,1);
TT.at<float>(0,2)=T.at<float>(2,0);
TT.at<float>(1,2)=T.at<float>(2,1);
cv::Mat c = cv::Mat(a.rows,a.cols,CV_8U);
imgaffine(a,c,TT);
cv::namedWindow("test");
cv::imshow("test",c);
cv::waitKey();
return 0;
}
void imgaffine(cv::Mat in,cv::Mat out,cv::Mat matrix)
{
float* data_0=matrix.ptr<float>(0);
float* data_1=matrix.ptr<float>(1);
float a_00,a_01,a_02;
float a_10,a_11,a_12;
a_00=data_0[0];
a_01=data_0[1];
a_02=data_0[2];
a_10=data_1[0];
a_11=data_1[1];
a_12=data_1[2];
int width =out.cols;
int height =out.rows;
for(int j=0;j<height;j++)
{
uchar* data_out = out.ptr<uchar>(j);
for(int i=0;i<width;i++)
{
float y_in=(a_10*i - a_10*a_02 + a_00*a_12 - a_00*j)/(a_10*a_01 - a_00*a_11);
float x_in=(a_11*i - a_01*j - a_11*a_02 + a_12*a_01)/(a_11*a_00 - a_01*a_10);
if(x_in>in.cols || y_in>in.rows || x_in<0 || y_in<0)
data_out[i]=0;
else
{
//
//不插值,直接替换
/*
int xx=(int)(x_in);
int yy=(int)(y_in);
uchar* zhizhen = in.ptr<uchar>(yy);
data_out[i]=zhizhen[xx];
*/
/
//双线型插值///
int xx=(int)(x_in);
int yy=(int)(y_in);
int y1=yy+1;
uchar* zhizhen = in.ptr<uchar>(yy);
if(yy<511)
{
uchar* zhizhen1 = in.ptr<uchar>(y1);
int aa=zhizhen[xx],
bb=zhizhen[xx+1],
cc=zhizhen1[xx],
dd=zhizhen1[xx+1];
float r1=aa+(bb-aa)*(x_in-xx);
float r2=cc+(dd-cc)*(x_in-xx);
float r3=r1+(r2-r1)*(y_in-yy);
data_out[i]=(uchar)(r3);
}
else
data_out[i]=zhizhen[xx];
}
}
}
}
最近在往zedboard上面移植opencv的算法,一切都挺顺利的
只是有一个意料之外的问题
在arm上面做仿射变换时,得到的是一个错误的图像
刚开始怀疑是opencv库版本比较低的问题
可是换了高版本的库以后还是没用
这期间有一个比较蠢的错误
首先反思一下
就是设置opencv库的路径的时候,因为比较懒,没有复制文件路径,而是直接把2.3.1替换为2.4.8,结果没有注意文件夹名字的大小写问题
浪费了一天时间
昨天做linaro的图形界面
也是因为比较懒
没有重新制作文件系统
浪费了一天时间
到了今天
自己编写仿射变换的函数时
想偷懒,一直在师兄之前写的一个程序的基础上面改
改了一天没弄好
50+的代码
写了一天
结果刚才痛下决心自己重头写
一次通过!
事实证明,往往自己觉得最麻烦的方案才是最正确的方案
</pre><pre code_snippet_id="298776" snippet_file_name="blog_20140417_1_3152139" name="code" class="cpp"><pre code_snippet_id="298776" snippet_file_name="blog_20140417_1_3152139" name="code" class="cpp">