其实就是用remap函数重映射
其中输入输出图像没什么好说的,
后面是映射表的x和y,这两个参数是用来建立映射的,也就是你把原来比如(22,25)的像素点给到输出图像(1,1)的像素点,就是把22给(1,1)的x,25给(1,1)的y。
注意,映射一般是有规律的,不然图像就乱了或者你想加密也行。
下面给出了几种映射的例子,只对y或者只对x或者xy都进行映射。
**其中在压缩部分就是抽样压缩(应该是叫这个名字),就是原图像的奇数或偶素行/列进行采样,从而达到缩小图像的目的。**比如原图有100行100列,我只取奇数行1、3、5、7、9和奇数列1、3、5、7、9等,最后得到的图像就是50*50的,图像缩小了但是也损失了一些数据。
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) = 2 * (col - src.cols * 0.25);
map_y.at<float>(row, col) = 2 * (row - src.rows * 0.25);
}
这里你计算一下就知道了,同样假设图像为100×100,那么if就是让25-75的行或列进去,,假如col为25,row为25,那么2*(25-100*25)=0,也就是在输出图像(25,25)的位置取原图像(0,0)位置的像素点,同样当row为25,col为26,那么在输出图像(25,26)位置取原图像(0,2)的像素
发现了没,它是每隔一个像素点取一个的,所以最后压缩了图像
当然如果最后加个0.5,那就变成取1、3、5、7…的奇数像素点了
#include<opencv2/opencv.hpp>
#include <iostream>
cv::Mat src, dst, map_x, map_y;
int index = 0;
const char* output_win = "rmap image";
void update_map();
int main()
{
src = cv::imread("E:/images/2mn.jpg");
if (!src.data) {
std::cout << "could not load image.....\n";
return -1;
}
char input_win[] = "input image";
cvNamedWindow(input_win,CV_WINDOW_AUTOSIZE);
cvNamedWindow(output_win, CV_WINDOW_AUTOSIZE);
cv::imshow(input_win, src);
map_x.create(src.size(), CV_32FC1);
map_y.create(src.size(), CV_32FC1);
int c = 0;
while (true) {
c = cv::waitKey(300);
if ((char)c == 27) break;
index = c % 4;
update_map();
cv::remap(src, dst, map_x, map_y, cv::INTER_LINEAR,cv::BORDER_CONSTANT, cv::Scalar(0, 0, 255));
cv::imshow(output_win, dst);
}
cv::waitKey(0);
return 0;
}
void update_map() {
//更改映射表
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) = 2 * (col - src.cols * 0.25);
map_y.at<float>(row, col) = 2 * (row - src.rows * 0.25);
}
//除中心位置外为黑色
else {
map_x.at<float>(row, col) = 0;
map_x.at<float>(row, col) = 0;
}
break;
//左右颠倒
case 1:
map_x.at<float>(row, col) = src.cols - col - 1;
map_y.at<float>(row, col) = row;
break;
//上下颠倒
case 2:
map_x.at<float>(row, col) = col;
map_y.at<float>(row, col) = src.rows - row - 1;
break;
case 3:
map_x.at<float>(row, col) = src.cols - col - 1;
map_y.at<float>(row, col) = src.rows - row - 1;
break;
default:
break;
}
}
}
}
ps:这些原画是W L O P画师创作的哦~