您的位置:首页 > 运维架构

Opencv学习之仿射变换、直方图均衡化

2017-06-23 13:44 423 查看
Opencv学习之仿射变换、直方图均衡化

Opencv学习之仿射变换–wrapAffine函数、getRotationMatrix2D函数

仿射变换,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。它保持了二维图形的“平直性”(直线经过变换之后依然是直线)和“平行性”(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。

仿射变换有如下三种常见的变换形式:

(1)旋转,rotation(线性变换)

(2)平移,translation(向量加)

(3)缩放,scale(线性变换)

*使用opencv函数warpAffine来实现一些简单的重映射

*使用opencv函数getRotationMatrix2D来获得旋转矩阵

void warpAffine(inputArray,outputArray,M,Size dsize,int flag=INTER_LINEAR,int borderMode=BORDER_CONSTANT,const Scalar & borderValue=Scalar())

*第一个参数,输入图像。

*第二个参数,输出结果。

*第三个参数,2x3的变换矩阵。

*第四个参数,输出图像的尺寸。

*第五个参数,插值方法,默认线性插值。

*第六个参数,边界像素模式。

*第七个参数,恒定的边界情况下取得值。

Mat getRotationMatrix2D(Point2f center,double angle,double scale)

*第一个参数,源图像的旋转中心

*第二个参数,旋转角度,角度为正值表示向逆时针旋转(坐标原点是左上角)

*第三个参数,缩放系数

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>

using namespace cv;
using namespace std;

//主函数
int main()
{
//载入图片
Mat srcImage=imread("/Users/new/Desktop/1.jpg");
if(!srcImage.data){printf("读取源图像srcImage错误~!\n");return false;}
//参数准备
//定义两组点
Point2f srcTriangle[3];
Point2f dstTriangle[3];
//定义一些Mat变量
Mat rotMat(2,3,CV_32FC1);
Mat warpMat(2,3,CV_32FC1);
Mat dstImage_warp,dstImage_warp_rotate;
//设置目标图像的大小和类型与源图像一致
dstImage_warp=Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());

//设置源图像和目标图像上的三组点以计算仿射变换
srcTriangle[0]=Point2f(0,0);
srcTriangle[1]=Point2f(static_cast<float>(srcImage.cols-1),0);
srcTriangle[2]=Point2f(0,static_cast<float>(srcImage.rows-1));
dstTriangle[0]=Point2f(static_cast<float>(srcImage.cols*0.0),static_cast<float>(srcImage.rows*0.33));
dstTriangle[1]=Point2f(static_cast<float>(srcImage.cols*0.65),static_cast<float>(srcImage.rows*0.35));
dstTriangle[2]=Point2f(static_cast<float>(srcImage.cols*0.15),static_cast<float>(srcImage.rows*0.6));
//求的仿射变换
warpMat=getAffineTransform(srcTriangle, dstTriangle);
//对源图像应用刚刚求得的仿射变换
warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());
//对图像进行缩放后旋转
//计算绕图像中点顺时针旋转30度缩放因子为0.8的旋转矩阵
Point center=Point(dstImage_warp.cols/2,dstImage_warp.rows/2);
double angle=-30.0;
double scale=0.8;
//通过上面的旋转信息求得旋转矩阵
rotMat=getRotationMatrix2D(center, angle, scale);
//旋转已缩放后的图像
warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());

//显示结果
imshow("image[origin]",srcImage);
imshow("image[warp]", dstImage_warp);
imshow("image[warp+rotate]", dstImage_warp_rotate);
//按下任意键退出
waitKey(0);
return 0;

}


原始图片:



变形后图片:



变形加旋转后图片:



Opencv学习之直方图均衡化–equalizeHist函数

当照片效果不尽如人意时,可以利用直方图均衡化来扩大图像的动态范围。直方图均衡化就是用一定的算法使直方图大致平和的方法。简而言之,直方图均衡化就是通过拉伸像素强度分布范围来增强图像对比度的一种方法。均衡化图像的动态范围扩大了,但其本质是扩大了量化间隔,而量化级别反而减少了,因此,原来灰度不同的像素经过处理后可能变相同,形成了一片相同灰度的区域,各区域之间有明显的边界,从而出现了伪轮廓。均衡化后的图片如果再对其均衡化,图像不会有任何变化。

直方图均衡化步骤:

(1)计算输入图像的直方图H

(2)进行直方图归一化,直方图的组距的和为255

(3)计算直方图积分

(4)以积分结果作为查询表进行图像变换

void equalizeHist(inputArray,outputArray)

*第一个参数,输入图像,需为8位单通道的图像。

*第二个参数,输出图像。

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

//主函数
int main()
{
//载入源图像
Mat srcImage,dstImage;
srcImage=imread("/Users/new/Desktop/2.jpg");
if(!srcImage.data){printf("读取源图像srcImage错误~!\n");return false;}

//转为灰度图并显示
cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);
imshow("image[gray]", srcImage);

//进行直方图均衡化
equalizeHist(srcImage, dstImage);

//显示结果
imshow("image[renderings]", dstImage);

waitKey(0);
return 0;
}




Opencv技巧

(1)定义Mat变量:Mat rotMat(2,3,CV_32FC1),{2x3,CV_[位数][带符号与否][类型前缀]C[通道数]}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv