7.3重映射:
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat srcImage, dstImage;
Mat map_x, map_y;
srcImage = imread("tsg.jpg",1);
if (!srcImage.data) { printf("读取图片错误\n");return false; }
imshow("原始图", srcImage);
//创建和原始图一样的效果图,x重映射,y重映射
dstImage.create(srcImage.size(), srcImage.type());
map_x.create(srcImage.size(), CV_32FC1);
map_y.create(srcImage.size(), CV_32FC1);
for (int j = 0;j < srcImage.rows;j++)
{
for (int i = 0;i < srcImage.cols;i++)
{
map_x.at<float>(j, i) = static_cast<float>(i);
map_y.at<float>(j, i) = static_cast<float>(srcImage.rows-j);
}
}
remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imwrite("7.3.jpg", dstImage);
imshow("效果图", dstImage);
waitKey(0);
return 0;
}
程序执行结果如图:
7.3.4综合示例程序:
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME "程序窗口"//定义一些辅助宏
Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;
int updata_map(int key);
static void ShowHelpText();
int main(int argc, char** argv)
{
system("color 2F");
ShowHelpText();
g_srcImage = imread("tsg.jpg", 1);
if (!g_srcImage.data) { printf("读取图片错误\n");return false; }
imshow("原始图", g_srcImage);
//创建和原始图一样的重映射,x重映射,y重映射
g_dstImage.create(g_srcImage.size(), g_srcImage.type());
g_map_x.create(g_srcImage.size(), CV_32FC1);
g_map_y.create(g_srcImage.size(), CV_32FC1);
namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME, g_srcImage);
while (1)
{
int key = waitKey(0);
if ((key & 255) == 27) {
cout << "程序退出\n";
break;
}
updata_map(key);
remap(g_srcImage, g_dstImage, g_map_x, g_map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow(WINDOW_NAME, g_dstImage);
}
return 0;
}
int updata_map(int key)
{
//双层循环,遍历每一个像素点
for (int j = 0;j < g_srcImage.rows;j++)
{
for (int i = 0;i < g_srcImage.cols;i++)
{
switch (key)
{
case '1':
if (i > g_srcImage.cols*0.25&&i<g_srcImage.cols*0.75
&&j>g_srcImage.rows*0.25&&j < g_srcImage.rows*0.75)
{
g_map_x.at<float>(j, i) = static_cast<float>(2 * (i - g_srcImage.cols*0.25) + 0.5);
g_map_y.at<float>(j, i) = static_cast<float>(2 * (j - g_srcImage.rows*0.25) + 0.5);
}
else {
g_map_x.at<float>(j, i) = 0;
g_map_y.at<float>(j, i) = 0;
}
break;
case'2':
g_map_x.at<float>(j, i) = static_cast<float>(i);
g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows-j);
break;
case'3':
g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols-i);
g_map_y.at<float>(j, i) = static_cast<float>(j);
break;
case'4':
g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols-i);
g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j);
break;
}
}
}
return 1;
}
static void ShowHelpText()
{
printf("\n欢迎来到重映射示例程序\n");
printf("\n按键操作说明:\n");
printf("\tESC退出程序");
printf("\t1第一重映射方式\n");
printf("\t2第二重映射方式\n");
printf("\t3第二重映射方式\n");
printf("\t4第四重映射方式\n");
}
程序执行结果如图:
7.4仿射变换
#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();
int main()
{
system("color 1A");
ShowHelpText();
Point2f srcTriangle[3];
Point2f dstTriangle[3];
Mat rotMat(2, 3, CV_32FC1);
Mat warpMat(2, 3, CV_32FC1);
Mat srcImage, dstImage_warp, dstImage_warp_rotate;
srcImage = imread("tsg.jpg", 1);
if (!srcImage.data) { printf("读取图片错误\n");return false; }
//设置目标图像大小和类型与源图像一致
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[0] = Point2f(static_cast<float>(srcImage.cols*0.15),
static_cast<float>(srcImage.rows*0.6));
//求得仿射变换矩阵
warpMat = getAffineTransform(srcTriangle, dstTriangle);
//应用warpAffine()函数
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(WINDOW_NAME1, srcImage);
imshow(WINDOW_NAME2, dstImage_warp);
imshow(WINDOW_NAME3, dstImage_warp_rotate);
waitKey(0);
return 0;
}
static void ShowHelpText()
{
printf("\n\t欢迎来到仿射变换示例程序\n");
}
程序执行结果如图:
7.5 直方图均衡化:
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main() {
Mat srcImage, dstImage;
srcImage = imread("tsg.jpg", 1);
if (!srcImage.data) { printf("读取图片错误\n");return false; }
//转化为灰度图并显示
cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);
imshow("原始图", srcImage);
//进行直方图均衡化
equalizeHist(srcImage, dstImage);
imshow("直方图均衡化后的图", dstImage);
waitKey(0);
return 0;
}
程序执行结果如图: