日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv Remap 图像的映射

發布時間:2025/4/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv Remap 图像的映射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

重映射是什么意思?

  • 把一個圖像中一個位置的像素放置到另一個圖片指定位置的過程.

  • 為了完成映射過程, 有必要獲得一些插值為非整數像素坐標,因為源圖像與目標圖像的像素坐標不是一一對應的.

  • 我們通過重映射來表達每個像素的位置??:

    這里??是目標圖像,??是源圖像,??是作用于??的映射方法函數.

  • 讓我們來思考一個快速的例子. 想象一下我們有一個圖像??, 我們想滿足下面的條件作重映射:

    會發生什么? 圖像會按照??軸方向發生翻轉. 例如, 源圖像如下:

    看到紅色圈關于 x 的位置改變(??軸水平翻轉):

  • 通過 OpenCV 的函數?remap?提供一個簡單的重映射實現.

代碼

  • 本程序做什么?
    • 裝載一幅圖像.
    • 程序按秒循環, 在一個窗口中順序出現4種重映射過程對相同的圖像.
    • 等待用戶按 ‘ESC’ 鍵退出程序。
  • 下面是本教程代碼. 你也可以從?這里?下載。
  • #include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>#include <stdio.h>using namespace cv;/// Global variablesMat src, dst;Mat map_x, map_y;char* remap_window = "Remap demo";int ind = 0;/// Function Headersvoid update_map( void );/** * @function main */int main( int argc, char** argv ){/// Load the imagesrc = imread( argv[1], 1 );/// Create dst, map_x and map_y with the same size as src:dst.create( src.size(), src.type() );map_x.create( src.size(), CV_32FC1 );map_y.create( src.size(), CV_32FC1 );/// Create windownamedWindow( remap_window, CV_WINDOW_AUTOSIZE );/// Loopwhile( true ){/// Each 1 sec. Press ESC to exit the programint c = waitKey( 1000 );if( (char)c == 27 ){ break; }/// Update map_x & map_y. Then apply remapupdate_map();remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );/// Display resultsimshow( remap_window, dst );}return 0;}/** * @function update_map * @brief Fill the map_x and map_y matrices with 4 types of mappings */void update_map( void ){ind = ind%4;for( int j = 0; j < src.rows; j++ ){ for( int i = 0; i < src.cols; i++ ){switch( ind ){case 0:if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ){map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;}else{ map_x.at<float>(j,i) = 0 ;map_y.at<float>(j,i) = 0 ;}break;case 1:map_x.at<float>(j,i) = i ;map_y.at<float>(j,i) = src.rows - j ;break;case 2:map_x.at<float>(j,i) = src.cols - i ;map_y.at<float>(j,i) = j ;break;case 3:map_x.at<float>(j,i) = src.cols - i ;map_y.at<float>(j,i) = src.rows - j ;break;} // end of switch}}ind++; }

    說明

  • 首先準備程序用到的變量:

    Mat src, dst; Mat map_x, map_y; char* remap_window = "Remap demo"; int ind = 0;
  • 加載一幅圖像:

    src = imread( argv[1], 1 );
  • 創建目標圖像和兩個映射矩陣.( x 和 y )

    dst.create( src.size(), src.type() ); map_x.create( src.size(), CV_32FC1 ); map_y.create( src.size(), CV_32FC1 );
  • 創建一個窗口用于展示結果.

    namedWindow( remap_window, CV_WINDOW_AUTOSIZE );
  • 建立一個間隔1000毫秒的循環,每次循環執行更新映射矩陣參數并對源圖像進行重映射處理(使用?mat_x?和?mat_y),然后把更新后的目標圖像顯示出來:

    while( true ) {/// Each 1 sec. Press ESC to exit the programint c = waitKey( 1000 );if( (char)c == 27 ){ break; }/// Update map_x & map_y. Then apply remapupdate_map();remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );/// Display resultsimshow( remap_window, dst ); }

    上面用到的重映射函數?remap. 參數說明:

    • src: 源圖像
    • dst: 目標圖像,與?src?相同大小
    • map_x: x方向的映射參數. 它相當于方法??的第一個參數
    • map_y: y方向的映射參數. 注意?map_y?和?map_x?與?src?的大小一致。
    • CV_INTER_LINEAR: 非整數像素坐標插值標志. 這里給出的是默認值(雙線性插值).
    • BORDER_CONSTANT: 默認

    如何更新重映射矩陣?mat_x?和?mat_y? 請繼續看:

  • 更新重映射矩陣:?我們將分別使用4種不同的映射:

  • 圖像寬高縮小一半,并顯示在中間:

    所有成對的參數??處理后都符合:??和?

  • 圖像上下顛倒:?

  • 圖像左右顛倒:?

  • 同時執行b和c的操作:?

  • 下面的代碼片段說明上述的映射過程. 在這里?map_x?代表第一個坐標?h(i,j)?,?map_y?是第二個坐標.

    for( int j = 0; j < src.rows; j++ ) { for( int i = 0; i < src.cols; i++ ){switch( ind ){case 0:if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ){map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;}else{ map_x.at<float>(j,i) = 0 ;map_y.at<float>(j,i) = 0 ;}break;case 1:map_x.at<float>(j,i) = i ;map_y.at<float>(j,i) = src.rows - j ;break;case 2:map_x.at<float>(j,i) = src.cols - i ;map_y.at<float>(j,i) = j ;break;case 3:map_x.at<float>(j,i) = src.cols - i ;map_y.at<float>(j,i) = src.rows - j ;break;} // end of switch}}ind++; }

    結果

  • 上面的代碼編譯后, 運行時給一個圖片路徑參數. 例如,使用下面的圖片:

  • 圖像寬高縮小一半,并顯示在中間:

  • 圖像上下顛倒:

  • 圖像左右顛倒:

  • 兩個方向同時顛倒:

  • 總結

    以上是生活随笔為你收集整理的opencv Remap 图像的映射的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。