重映射的概念
重映射,就是把一幅圖像中某位置的像素放置到另一個圖片指定位置的過程。
實現重映射:remap 函數
將圖像進行重映射幾何變換,基於的公式為:dst (x, y) = src ( mapx (x, y), mapy (x, y) )。即 mapx 在(x,y)位置上存儲的是目標像素的橫坐標,mapy 在(x,y)位置上存儲的是目標像素的縱坐標。
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());
- src,輸入圖像,即源圖像,填灰度圖或真彩圖均可。
- dst,輸出圖像,需要和源圖像有一樣的尺寸和類型。
- map1,即 mapx。
- map2,即 mapy 。
- interpolation,插值方法。插值就是根據已知數據點(條件),來預測未知數據點值得方法。在重映射過程中,圖像的大小可能發生改變。此時像素與像素之間的關系就不是一一對應關系,因此在重映射過程中,可能會涉及到像素值的插值計算。可選插值方式如下:
INTER_NEAREST(最近鄰差值)
INTER_LINEAR(雙線性插值,一般選擇這種方式)
INTER_CUBIC(雙三次樣條插值,超過 4×4 像素鄰域內的雙三次插值)
INTER_LANCZOS4(Lanczos 插值,超過 8×8 像素鄰域的 Lanczos 插值)
- borderMode,邊界擴展類型。默認值為 BORDER_CONSTANT,詳解鏈接:https://www.cnblogs.com/bjxqmy/p/12306276.html
- borderValue ,只有當 borderMode取值為 BORDER_CONSTANT 時,這個參數才會被使用,邊界會被填充成 borderValue 指定的顏色。
代碼示例:
#include<opencv.hpp> #include<iostream>
using namespace std; using namespace cv; Mat src; int choice = 0; void change_choice(int, void*) { Mat dst; Mat x_map = Mat(src.size(), CV_32FC1), y_map = Mat(src.size(), CV_32FC1); for (int i = 0; i < src.rows; i++) { float* x_rows = x_map.ptr<float>(i); float* y_rows = y_map.ptr<float>(i); for (int j = 0; j < src.cols; j++) { switch (choice){ case 0://180°旋轉
x_rows[j] = static_cast<float>(src.cols - j); y_rows[j] = static_cast<float>(src.rows - i); break; case 1://縮小為原來的 1/2
if (j > src.cols*0.25&&j<src.cols*0.75&&i>src.rows*0.25&&i < src.rows*0.75) { x_rows[j] = static_cast<float>(2 * (j - src.cols*0.25)); y_rows[j] = static_cast<float>(2 * (i - src.rows*0.25)); } break; } } } remap(src, dst, x_map, y_map, INTER_LINEAR); imshow("dst", dst); } int main() { src = imread("C:/Users/齊明洋/Desktop/1.jpg"); imshow("src", src); namedWindow("dst"); createTrackbar("choice", "dst", &choice, 1, change_choice); change_choice(0, 0); waitKey(0); }
效果演示:
借鑒博客:https://www.cnblogs.com/HL-space/p/10546595.html
https://blog.csdn.net/weixin_39746114/article/details/82467458