opencv学习笔记(二十三)图像的像素重映射

1.重映射概念

把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像。注意是位置的改动,像素值不变。

2.API介绍

void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar())

src:输入图像

dst:输出图像

map1:x方向的映射表

map2:y方向的映射表

interpolation:插值方式,有四种插值方式:(1)INTER_NEAREST——最近邻插值
                                                                     (2)INTER_LINEAR——双线性插值(默认)

                                                                     (3)INTER_CUBIC——双三样条插值(默认)

                                                                     (4)INTER_LANCZOS4——lanczos插值(默认)

intborderMode:边界模式

borderValue:边界颜色

3.代码实现

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;

char inputName[] = "input name";
char outputName[] = "output name";
Mat src, dst, mapX, mapY;
int index=0;
void ReMap(void);
int main()
{
	src = imread("D:/demo.jpg");
	if (src.empty())
	{
		cout << "找不到图像!" << endl;
		return -1;
	}
	namedWindow(inputName, CV_WINDOW_AUTOSIZE);
	imshow(inputName, src);
	mapX.create(src.size(), CV_32FC1);
	mapY.create(src.size(), CV_32FC1);
	int c=0;
	while (true)
	{
		c = waitKey(500);
		if ((char)c==27)
		{
			break;
		}
		index = c % 4;//保证index与c的值一致,初始化值为Waitkey(500),int一直是255
		ReMap();
		remap(src, dst, mapX, mapY, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 255));
		imshow(outputName, dst);
	}

	waitKey(0);
	return 0;
}
void ReMap(void)
{
	for (int row = 0; row <src.rows; row++)
	{
		for (int col = 0; col<src.cols; col++)
		{
			switch (index)
			{
			case 0://把图缩小到1/2,不懂这里的算法
				if (col > (src.cols*0.25) && col<(src.cols*0.75) && row>(src.rows*0.25) && row < (src.rows*0.75))
				{
					mapX.at<float>(row, col) = 2 * (col - src.cols*0.25f);
					mapY.at<float>(row, col) = 2 * (row - src.rows*0.25f);
				}
				else
				{
					mapX.at<float>(row, col) = 260;
					mapY.at<float>(row, col) = 260;
				}
				break;
			case 1://横向翻转
				mapX.at<float>(row, col) = (float)src.cols - col-1;//应该使用索引
				mapY.at<float>(row, col) = (float)row;
				break;
			case 2://纵向翻转
				mapX.at<float>(row, col) = (float)col;
				mapY.at<float>(row, col) = (float)src.rows - row-1;
				break;
			case 3://横纵向同时翻转
				mapX.at<float>(row, col) = (float)src.cols - col-1;
				mapY.at<float>(row, col) = (float)src.rows - row-1;
				break;
			}
		}
	}
}

其中缩小一半的地方计算规则不太明白。其余几个翻转比较容易懂。

4.运行结果

发布了53 篇原创文章 · 获赞 9 · 访问量 3278

猜你喜欢

转载自blog.csdn.net/weixin_41039168/article/details/96565413
今日推荐