/*
*像素重映射 先想一下数学上面的映射的概念
简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像。
API介绍cv::remap
Remap(
InputArray src,// 输入图像 没有要求
OutputArray dst,// 输出图像
InputArray map1,// x 映射表 位数必须是CV_32FC1或者CV_32FC2 map1和map2是两个映射表,映射表把像素完全一一映射
InputArray map2,// y 映射表
int interpolation,// 选择的插值方法,常见线性插值,可选择立方等
int borderMode,// BORDER_CONSTANT 边缘的填充方式
const Scalar borderValue// color 表示border用什么颜色来填充
)
*/
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat src, dst, map_x, map_y;
const char* OUTPUT_TITLE = "remap demo";
int index = 0;
void update_map(void); //为了给程序一个自动运行的功能
int main()
{
Mat src, dst;
src = imread("D:/A_Graduation/Learning/qt/image/tangwei.jpg");
imshow("src", src);
//建立映射表
map_x.create(src.size(), CV_32FC1); //参数分别为:和输入图像的大小一样,32位单通道的图像
map_y.create(src.size(), CV_32FC1);
for (int row = 0; row < src.rows; row++)
{
for (int col = 0; col < src.cols; col++)
{
if (col > (src.cols * 0.25) && col <= (src.cols*0.75) && row > (src.rows*0.25) && row <= (src.rows*0.75))
{
map_x.at<float>(row, col) = (float)(2 * (col - src.cols*0.25)); //remap我们知道可以将图像灰度分布从一个分布映射到另外一个分布,然后在得到映射后的像素值即可。
map_y.at<float>(row, col) = (float)(2 * (row - src.rows*0.25));
}
else {
map_x.at<float>(row, col) = 0;
map_y.at<float>(row, col) = 0;
}
}
}
// int c = 0;
// while (true) {
// c = waitKey(500);
// if ((char)c == 27) {
// break;
// }
// index = c % 4;
// update_map();
// //------api调用------ 插值方法选线性插值
// remap(src, dst, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
// imshow(OUTPUT_TITLE, dst);
// }
remap(src, dst, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow(OUTPUT_TITLE, dst);
waitKey(0);
return 0;
}
void update_map(void)
{
//像素映射的工作
for (int row = 0; row < src.rows; row++)
{
for (int col = 0; col < src.cols; col++)
{
switch (index)
{
case 0: //最终得到的大小只有原来图像的一半大
if (col > (src.cols * 0.25) && col <= (src.cols*0.75) && row > (src.rows*0.25) && row <= (src.rows*0.75))
{
map_x.at<float>(row, col) = (float)(2 * (col - (src.cols*0.25) + 0.5));
map_y.at<float>(row, col) = (float)(2 * (row - (src.rows*0.25) + 0.5));
}
else {
map_x.at<float>(row, col) = 0;
map_y.at<float>(row, col) = 0;
}
break;
case 1: //列做映射,行不做映射
map_x.at<float>(row, col) = (float)(src.cols - col - 1);
map_y.at<float>(row, col) = (float)row;
break;
case 2: //行变化,列不变
map_x.at<float>(row, col) = (float)col;
map_y.at<float>(row, col) = (float)(src.rows - row - 1);
break;
case 3: //行列都变
map_x.at<float>(row, col) = (float)(src.cols - col - 1);
map_y.at<float>(row, col) = (float)(src.rows - row - 1);
break;
}
}
}
}