《OpenCV3编程入门》学习笔记7 图像变换(三 )重映射
7.3 重映射
7.3.1 概念
1.重映射是把圖像中某位置的像素放置到另一圖片指定位置的過(guò)程,通過(guò)重映射表達(dá)像素位置:
???????????????????g(x,y)=f(h(x,y))
??????????g()是目標(biāo)圖像,f()是原圖像,h(x,y)是作用于(x,y)的映射方法函數(shù)
2.函數(shù):remap()函數(shù),根據(jù)指定的映射形式,將源圖像進(jìn)行重映射幾何變換,基于以下公式:
????????????????
3.函數(shù)原型:
void remap(InputArray src, OuptutArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
4.參數(shù)說(shuō)明:
(1)輸入圖像,單通道8位或浮點(diǎn)型圖像
(2)輸出圖像,與原圖像有一樣尺寸和類型
(3)兩種可能表示:1)表示點(diǎn)(x,y)的第一個(gè)映射 2)表示CV_16SC2、CV_32FC1或CV_32FC2類型的x值
(4)兩種可能表示:1)map1表示點(diǎn)(x,y)時(shí),參數(shù)不代表任何值 2)表示CV_16UC1、CV_32FC1類型的y值
(5)插值方式,可選插值方式:
???1)INTER_NEAREST–最近鄰插值
???2)INTER_LINEAR–雙線性插值(默認(rèn)值)
???3)INTER_CUBIC–雙三次樣條插值(超過(guò)44像素鄰域內(nèi)的雙三次插值)
???4)INTER_LANCZOS4–Lanczos插值(超過(guò)88像素領(lǐng)域的Lanczos插值)
(6)邊界模式,默認(rèn)值BORDER_CONSTANT,表示目標(biāo)圖像中“離群點(diǎn)”像素值不會(huì)被此函數(shù)修改
(7)當(dāng)有常數(shù)邊界時(shí)使用的值,默認(rèn)Scalar()
5.調(diào)用示例:
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{//變量定義Mat srcImage, dstImage;Mat map_x, map_y;//載入原圖srcImage = imread("love.jpg");if (!srcImage.data){printf("載入原圖失敗~!\n");return false;}//顯示原圖imshow("【原始圖】", srcImage);//創(chuàng)建和原始圖一樣的效果圖,x映射圖,y映射圖dstImage.create(srcImage.size(), srcImage.type());map_x.create(srcImage.size(), CV_32FC1);map_y.create(srcImage.size(), CV_32FC1);//雙層循環(huán),遍歷每一個(gè)像素點(diǎn),改變map_x 與 map_y的值for (int i = 0; i < srcImage.rows; i++){for (int j = 0; j < srcImage.cols; j++){map_x.at<float>(i, j) = static_cast<float>(j);map_y.at<float>(i, j) = static_cast<float>(srcImage.rows - i);}}//重映射操作remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));//顯示效果圖imshow("【效果圖】", dstImage);waitKey(0);return 0;
}
運(yùn)行效果:
7.3.2 綜合示例
/*
效果:
按鍵控制實(shí)現(xiàn)4種不同重映射模式
*/
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME "【程序窗口】"//全局變量
Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;//全局函數(shù)
int update_map(int key);
static void ShowHelpText();int main()
{//改變console字體顏色system("color 2F");//顯示幫助文字ShowHelpText();//【1】載入原圖g_srcImage = imread("3.jpg");if (!g_srcImage.data){ printf("載入原圖失敗~!\n");return false; }//【2】創(chuàng)建和原圖一樣的效果圖,x重映射圖,y重映射圖g_dstImage.create(g_srcImage.size(), g_srcImage.type());g_map_x.create(g_srcImage.size(), CV_32FC1);g_map_y.create(g_srcImage.size(), CV_32FC1);//【3】創(chuàng)建窗口并顯示namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);imshow(WINDOW_NAME, g_srcImage);//【4】輪詢按鍵,更新map_x和map_y的值,進(jìn)行重映射操作并顯示效果圖while (1){//獲取鍵盤按鍵 int key = waitKey(0);//判斷ESC是否按下,若按下便退出 if ((key & 255) == 27){cout << "程序退出...........\n";break;}//根據(jù)按下的鍵盤按鍵來(lái)更新 map_x & map_y的值. 然后調(diào)用remap( )進(jìn)行重映射update_map(key);remap(g_srcImage, g_dstImage, g_map_x, g_map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));//顯示效果圖imshow(WINDOW_NAME, g_dstImage);}return 0;
}//update_map( )函數(shù):根據(jù)按鍵來(lái)更新map_x與map_x的值
int update_map(int key)
{//雙層循環(huán),遍歷每一個(gè)像素點(diǎn)for (int j = 0; j < g_srcImage.rows; j++){for (int i = 0; i < g_srcImage.cols; i++){switch (key){case '1': // 鍵盤【1】鍵按下,進(jìn)行第一種重映射操作if (i > g_srcImage.cols*0.25 && i < g_srcImage.cols*0.75 && j > g_srcImage.rows*0.25 && j < g_srcImage.rows*0.75){g_map_x.at<float>(j, i) = static_cast<float>(2 * (i - g_srcImage.cols*0.25) + 0.5);g_map_y.at<float>(j, i) = static_cast<float>(2 * (j - g_srcImage.rows*0.25) + 0.5);}else{g_map_x.at<float>(j, i) = 0;g_map_y.at<float>(j, i) = 0;}break;case '2': // 鍵盤【2】鍵按下,進(jìn)行第二種重映射操作g_map_x.at<float>(j, i) = static_cast<float>(i);g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j);break;case '3': // 鍵盤【3】鍵按下,進(jìn)行第三種重映射操作g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i);g_map_y.at<float>(j, i) = static_cast<float>(j);break;case '4': // 鍵盤【4】鍵按下,進(jìn)行第四種重映射操作g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i);g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j);break;}}}return 0;
}static void ShowHelpText()
{printf("\n\n\n\t歡迎來(lái)到重映射示例程序~\n\n");printf("\n\n\t按鍵操作說(shuō)明: \n\n");printf("\t\t鍵盤按鍵【ESC】- 退出程序\n");printf("\t\t鍵盤按鍵【1】- 第一種映射方式\n");printf("\t\t鍵盤按鍵【2】- 第二種映射方式\n");printf("\t\t鍵盤按鍵【3】- 第三種映射方式\n");printf("\t\t鍵盤按鍵【4】- 第四種映射方式\n");
}
運(yùn)行效果:
?????????映射模式1????????????????映射模式2
????????映射模式3?????????????????映射模式4
總結(jié)
以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记7 图像变换(三 )重映射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《OpenCV3编程入门》学习笔记7 图
- 下一篇: 上海欢乐谷过山车多高的孩子可以玩