1. 仿射变换
仿射变换(Affine Transformation),一个向量空间经过一次线性变换再经过一次平移,变换为另一个向量空间的过程。
它保持了二维图形的平直性和平行性,即直线变换后还是直线,平行线变换后还是平行线。它可以用乘以一个旋转矩阵再加上一个平移矩阵得到。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【经过Warp后的图像】" //为窗口标题定义的宏
#define WINDOW_NAME3 "【经过Warp和Rotate后的图像】" //为窗口标题定义的宏
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
static void ShowHelpText( );
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
//【0】改变console字体颜色
system("color 1F");
//【1】参数准备
//定义两组点,代表两个三角形
Point2f srcTriangle[3];
Point2f dstTriangle[3];
//定义一些Mat变量
Mat rotMat( 2, 3, CV_32FC1 );
Mat warpMat( 2, 3, CV_32FC1 );
Mat srcImage, dstImage_warp, dstImage_warp_rotate;
//【2】加载源图像并作一些初始化
srcImage = imread( "1.jpg", 1 );
if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
// 设置目标图像的大小和类型与源图像一致
dstImage_warp = Mat::zeros( srcImage.rows, srcImage.cols, srcImage.type() );
//【3】设置源图像和目标图像上的三组点以计算仿射变换
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));
//【4】求得仿射变换
warpMat = getAffineTransform( srcTriangle, dstTriangle );
//【5】对源图像应用刚刚求得的仿射变换
warpAffine( srcImage, dstImage_warp, warpMat, dstImage_warp.size() );
//【6】对图像进行缩放后再旋转
// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
Point center = Point( dstImage_warp.cols/2, dstImage_warp.rows/2 );
double angle = -50.0;
double scale = 0.6;
// 通过上面的旋转细节信息求得旋转矩阵
rotMat = getRotationMatrix2D( center, angle, scale );
// 旋转已缩放后的图像
warpAffine( dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size() );
//【7】显示结果
imshow( WINDOW_NAME1, srcImage );
imshow( WINDOW_NAME2, dstImage_warp );
imshow( WINDOW_NAME3, dstImage_warp_rotate );
// 等待用户按任意按键退出程序
waitKey(0);
return 0;
}
1.1 getAffineTransform()函数
Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
//! computes 2x3 affine transformation matrix that is inverse to the specified 2x3 affine transformation.
2. 直方图均衡化
直方图均衡化可以扩大图像动态范围,均衡化通过拉伸像素分布范围来增强图像对比度。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
//--------------------------------------【main( )函数】-----------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
// 【1】加载源图像
Mat srcImage, dstImage;
srcImage = imread( "1.jpg", 1 );
if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定图片存在~! \n"); return false; }
// 【2】转为灰度图并显示出来
cvtColor( srcImage, srcImage, CV_BGR2GRAY );
imshow( "原始图", srcImage );
// 【3】进行直方图均衡化
equalizeHist( srcImage, dstImage );
// 【4】显示结果
imshow( "经过直方图均衡化后的图", dstImage );
// 等待用户按键退出程序
waitKey(0);
return 0;
}
2.1 equalizeHist()
void equalizeHist( InputArray src, OutputArray dst );