Opencv remap函数
- 函数签名
- 实例
- 应用
- 亚像素信息
- 扭曲特效
函数签名
void cv::remap ( InputArray src,
OutputArray dst,
InputArray map1,
InputArray map2,
int interpolation,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
将通用几何变换应用于图像。dst
的尺寸应当应当和map1
、map2
一致,而dst
的数据类型则应同src
一致。
map1
以及map2
共同表征了映射方式,代表dst的某个像素值来自于src中的哪一个点。也就是说,dst的每个像素的值都可以从src中某个位置得到,计算方式则如下:
dst(x,y) = src(map1(x, y), map2(x, y));
由于计算的取值位置(map1(x, y), map2(x, y))
可能为非整数,需要在src中通过某种插值方式interpolation
插值计算得到这一点的像素值。
borderMode
——未定义的像素如何填充,类似于卷积时怎么补充边界。
可用的interpolation以及borderMode方式可查阅官网文档。
实例
int remap_test()
{// 映射关系,简单的平移{Mat srcImage;srcImage = imread("ying.png", 1);//resize(srcImage, srcImage, Size(srcImage.cols / 2, srcImage.rows / 2));Mat dstImage;Mat map_x, map_y;float shift_x = 250.5, shift_y = 150.7;int dst_w = 400, dst_h = 300;Rect dstROI(shift_x, shift_y, dst_w, dst_h);std::vector<float> t_x, t_y;int w = 0, h = 0;for (int w = 0; w < dst_w; w++) {t_x.push_back(static_cast<float>(w + shift_x));}for (int h = 0; h < dst_h; h++) {t_y.push_back(static_cast<float>(h + shift_y));}cout << "tx: " << t_x.size() << " ty: " << t_y.size() << endl;cv::repeat(cv::Mat(t_x).t(), t_y.size(), 1, map_x);cv::repeat(cv::Mat(t_y), 1, t_x.size(), map_y);remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(40, 40, 40));rectangle(srcImage, dstROI, Scalar(0, 0, 255));imshow("src", srcImage);imshow("remap result", dstImage);waitKey(0);}// 波纹效果{Mat srcImage;srcImage = imread("ying.png", 1);resize(srcImage, srcImage, Size(srcImage.cols / 2, srcImage.rows / 2));Mat dstImage;Mat map_x, map_y;map_x.create(srcImage.size(), CV_32FC1);map_y.create(map_x.size(), CV_32FC1);dstImage.create(map_x.size(), srcImage.type());for (int j = 0; j < srcImage.rows; j++){for (int i = 0; i < srcImage.cols; i++){//改变map_x & map_y的值.map_x.at<float>(j, i) = static_cast<float>(i + 5 * cos(j / 10.f));map_y.at<float>(j, i) = static_cast<float>(j);}}remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(255, 0, 0));imshow("src", srcImage);imshow("remap result", dstImage);waitKey(0);}return 0;
}
可以看到新图片的第一个像素来自原图的红色标记处(shift_x = 250, shift_y = 150)
,而超出原图区域的像素,由于BORDER_CONSTANT被指定为设定的值。
应用
亚像素信息
如例子1所示,通过插值获取图像区域中非整数位置的像素信息,也就是某些场景中所谓的亚像素信息。
扭曲特效
如例子2所示,可以实现对图像的扭曲效果,哈哈镜、波纹、乃至更加复杂的效果都可以通过调整映射矩阵的方式实现。