福州什么推广网站好,石家庄建设一个网站多少钱,网站一级域名申请,wordpress图片上传地址文章目录 前言1.像素重映射理论基础2.代码实现(1) remap()细节(2)水平翻转(2)垂直翻转(3)旋转 180 度(4)径向扭曲 3.完整代码 前言
像素重映射将图像中的每个像素映射到新位置#xff0c;实现图像的扭曲、校正等操作。在 OpenCV 中#xff0c;cv::remap() 函数就是用于实现这… 文章目录 前言1.像素重映射理论基础2.代码实现(1) remap()细节(2)水平翻转(2)垂直翻转(3)旋转 180 度(4)径向扭曲 3.完整代码 前言
像素重映射将图像中的每个像素映射到新位置实现图像的扭曲、校正等操作。在 OpenCV 中cv::remap() 函数就是用于实现这种功能的。本文将详细介绍像素重映射的基本原理以及在 OpenCV 中的实现方法并给出完整代码。
1.像素重映射理论基础
像素重映射的原理是将图像的每个像素通过预定义的映射规则重新分配到新的位置。映射规则可以是任意的数学函数比如旋转、缩放、扭曲等甚至可以通过查表的方式进行非线性的映射。 像素重映射可以用以下公式表示 dst ( x ′ , y ′ ) src ( x , y ) \text{dst}(x, y) \text{src}(x, y) dst(x′,y′)src(x,y) 其中 (x, y) 是源图像中的像素位置(x, y) 是目标图像中的像素位置。通过映射函数可以将源图像的像素映射到目标图像的相应位置。
常见的重映射应用
图像扭曲将图像以某种方式进行扭曲处理使其变形。
镜头畸变校正通过重映射可以校正图像中由于镜头引起的畸变如鱼眼镜头畸变。
图像旋转与缩放可以将图像按照指定的角度和比例进行旋转与缩放。
2.代码实现
实验用到图像供学习使用sherlock.jpg
(1) remap()细节
cv::remap(
InputArray src,// 输入图像
OutputArray dst,// 输出图像
InputArray map1,// x 映射表 CV_32FC1/CV_32FC2
InputArray map2,// y 映射表
int interpolation,// 选择的插值方法常见线性插值可选择立方等
int borderMode,// 指定图像边界的处理方式默认为 BORDER_CONSTANT。
const Scalar borderValue// 用于边界像素的值默认是黑色。
)(2)水平翻转
将 map1 中的列坐标从右向左映射map2 保持原始的行坐标不变。
for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(src.cols - j - 1); // 水平翻转map2.atfloat(i, j) static_castfloat(i);}}Mat dst_hflip;remap(src, dst_hflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Horizontal Flip, WINDOW_AUTOSIZE);imshow(Horizontal Flip, dst_hflip);结果: (2)垂直翻转
将 map2 中的行坐标从下向上映射而 map1 保持列坐标不变。 // 2. 垂直翻转for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(j);map2.atfloat(i, j) static_castfloat(src.rows - i - 1); // 垂直翻转}}Mat dst_vflip;remap(src, dst_vflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Vertical Flip, WINDOW_AUTOSIZE);imshow(Vertical Flip, dst_vflip);结果 (3)旋转 180 度
同时进行水平和垂直翻转 // 3. 旋转 180 度for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(src.cols - j - 1); // 水平翻转map2.atfloat(i, j) static_castfloat(src.rows - i - 1); // 垂直翻转}}Mat dst_rotate180;remap(src, dst_rotate180, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Rotate 180 degrees, WINDOW_AUTOSIZE);imshow(Rotate 180 degrees, dst_rotate180);结果 (4)径向扭曲
通过对极坐标中的半径进行二次变换产生径向扭曲效果图像向中心点扭曲产生类似鱼眼镜头的效果。 // 4. 径向扭曲效果float cx src.cols / 2.0;float cy src.rows / 2.0;float radius min(cx, cy);for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {float dx j - cx;float dy i - cy;float r sqrt(dx * dx dy * dy);float theta atan2(dy, dx);float r_distorted radius * (r / radius) * (r / radius); // 径向扭曲map1.atfloat(i, j) cx r_distorted * cos(theta);map2.atfloat(i, j) cy r_distorted * sin(theta);}}Mat dst_radial;remap(src, dst_radial, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Radial Distortion, WINDOW_AUTOSIZE);imshow(Radial Distortion, dst_radial);结果 3.完整代码
#includeopencv2/opencv.hpp
#includehighgui.hpp
#includeiostream
#includemath.husing namespace cv;
using namespace std;void remap_image()
{cv::Mat src;src imread(sherlock.jpg);if (src.empty()) {printf(could not find the image...\n);return;}namedWindow(Source Image, WINDOW_AUTOSIZE);imshow(Source Image, src);//创建映射矩阵Mat map1(src.size(), CV_32FC1);Mat map2(src.size(), CV_32FC1);// 1. 水平翻转for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(src.cols - j - 1); // 水平翻转map2.atfloat(i, j) static_castfloat(i);}}Mat dst_hflip;remap(src, dst_hflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Horizontal Flip, WINDOW_AUTOSIZE);imshow(Horizontal Flip, dst_hflip);// 2. 垂直翻转for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(j);map2.atfloat(i, j) static_castfloat(src.rows - i - 1); // 垂直翻转}}Mat dst_vflip;remap(src, dst_vflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Vertical Flip, WINDOW_AUTOSIZE);imshow(Vertical Flip, dst_vflip);// 3. 旋转 180 度for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {map1.atfloat(i, j) static_castfloat(src.cols - j - 1); // 水平翻转map2.atfloat(i, j) static_castfloat(src.rows - i - 1); // 垂直翻转}}Mat dst_rotate180;remap(src, dst_rotate180, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Rotate 180 degrees, WINDOW_AUTOSIZE);imshow(Rotate 180 degrees, dst_rotate180);// 4. 径向扭曲效果float cx src.cols / 2.0;float cy src.rows / 2.0;float radius min(cx, cy);for (int i 0; i src.rows; i) {for (int j 0; j src.cols; j) {float dx j - cx;float dy i - cy;float r sqrt(dx * dx dy * dy);float theta atan2(dy, dx);float r_distorted radius * (r / radius) * (r / radius); // 径向扭曲map1.atfloat(i, j) cx r_distorted * cos(theta);map2.atfloat(i, j) cy r_distorted * sin(theta);}}Mat dst_radial;remap(src, dst_radial, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow(Radial Distortion, WINDOW_AUTOSIZE);imshow(Radial Distortion, dst_radial);waitKey(0);
}
int main()
{remap_image();return 0;
}