opencv图像重映射压缩

api

其实就是用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画师创作的哦~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值