摄像头采集到的图像进行镜像变换,最简单的方法是逐点扫描然后重新赋值给一个新的矩阵。但是一张普通质量的图像也有十万级个像素点,这种方式做镜像变换,速度应该会很慢。
但是如果可以以矩阵的方式进行处理,访问图像更快,程序执行的速度也就更快。
以矩阵的方式操作原理如下:
比如有矩阵A,
所以,在程序中先生成一张反对角矩阵,然后在每一帧图像右乘它,就可以了。但是在代码实现时,要注意矩阵相乘要保证数据类型一致(opencv要求CV_32FC1, CV_64FC1等等),可以用Mat::convertTo()来实现。而且图像采集进来是三通道的,我们要把三个通道分别处理以后,再重新组合成一张彩色图。这就需要用到split()和merge()函数。
#include
#include
using namespace std;
using namespace cv;
int main(){
//生成右乘矩阵
Mat inverse(300,300,CV_32F);
for(int i=0;ifor(int j=0;jif(i+j==inverse.rows-1) inverse.at<float>(i,j)=1;
else inverse.at<float>(i,j)=0;
}
}
VideoCapture capture(0);
capture.set(CAP_PROP_FRAME_WIDTH,300);
capture.set(CAP_PROP_FRAME_HEIGHT,180);
Mat frame(180,300,CV_32FC3);
Mat frameDisp(800,1440,CV_32FC3);
vector fms;
cout<<"inverse matrix created!"<if(!capture.isOpened())
{
cout<<"fail to open"<return -1;
}
namedWindow("frames");
//CV_WINDOW_NORMAL CV_WINDOW_AUTOSIZE
//CV_WINDOW_FULLSCREEN
//CV_WINDOW_FREERATIO CV_WINDOW_KEEPRATIO
setWindowProperty("frames",CV_WND_PROP_FULLSCREEN,CV_WINDOW_FULLSCREEN);
//CV_WND_PROP_FULLSCREEN CV_WND_PROP_AUTOSIZE CV_WND_PROP_ASPECTRATIO
while(1){
capture>>frame;
frame.convertTo(frame,CV_32FC3,1/255.0); //转换成可以相乘的矩阵数据类型
split(frame,fms);
fms.at(0)=fms.at(0)*inverse;
fms.at(1)=fms.at(1)*inverse;
fms.at(2)=fms.at(2)*inverse;
merge(fms,frame);
resize(frame,frameDisp,frameDisp.size());
cout<<"frame channels : "<"frames",frameDisp);
if(waitKey(5)==' ') return 0;
}
return 0;
}
Tips:
vector
补充:
在opencv里面,有一个flip()函数,可以进行图像的翻转。
其描述如下:
C++: void flip(InputArray src, OutputArray dst, int flipCode)
Python: cv2.flip(src, flipCode[, dst]) → dst
C: void cvFlip(const CvArr* src, CvArr* dst=NULL, int flip_mode=0 )
Python: cv.Flip(src, dst=None, flipMode=0) → None
Parameters:
src – input array.
dst – output array of the same size and type as src.
flipCode – a flag to specify how to flip the array; 0 means flipping around the x-axis and positive value (for example, 1) means flipping around y-axis. Negative value (for example, -1) means flipping around both axes (see the discussion below for the formulas).