緒:
重映射就是把一幅圖像中某個位置的像素放置到另一個圖像中指定位置的過程;
仿射變換是一個標的目的量空間進行一次線性變換并接上一個平移,變換為另一貫量空間的過程;
本文本家兒要分重映射和放射變換的功能;
以及若何利用的。
重映射remap:
重映射就是把一幅圖像中某個位置的像素放置到另一個圖像中指定位置的過程;
公式:
g(x,y)=f(h(x,y))
此中f就是映射體例;
在OpenCV中,利用remap函數實現重映射。
格局:
void remap(InputArray src, //輸入圖像
OutputArraydst, //輸出圖像
InputArray map1,//第一個映射
InputArray map2, //第二個映射
int interpolation, //插值
intborderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar()
)
重映射法式如下:
//根基重映射嘗試
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("0.jpg");
imshow("Src Pic", srcImage);
Mat dstImage, map_x, map_y;
dstImage.create(srcImage.size(), srcImage.type());
map_x.create(srcImage.size(), CV_32FC1);
map_y.create(srcImage.size(), CV_32FC1);
//遍歷每一個像素點,改變map_x & map_y的值,實現翻轉180度
for (int j = 0; j < srcImage.rows; j++)
{
for (int i = 0; i < srcImage.cols; i++)
{
map_x.at<float>(j, i) = static_cast<float>(i);//行不變
map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);//列翻轉
}
}
//進行重映射操作
remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("重映射結果圖", dstImage);
waitKey();
return 0;
}
【注】:
map_x和map_y:代表方針圖中的(x,y)點在原圖像的x坐標和y坐標;
仿射變換:
仿射變換是一個標的目的量空間進行一次線性變換并接上一個平移,變換為另一貫量空間的過程;
圖像進行仿射變換后的特點:
①二維圖像之間的相對位置關系連結不變,平行線依舊是平行線,且直線上的點的位置挨次連結不變;
②一個肆意的仿射變換都可以暗示為乘以一個矩陣(線性變換)接著再加上一個標的目的量(平移)的形式;
三種常見形式:
扭轉-rotation(線性變換)
平移-translation(標的目的量加)
縮放-scale(線性變換)
仿射變換流程:
仿射變換素質是一個2* 3的矩陣M乘上原圖的每個坐標,獲得方針圖的對應點坐標。
2*3矩陣M中的2暗示方針點坐標的x與y,3中的第三維是平移分量。
是以需要做的就是找到矩陣M;
OpenCV供給 getAffineTransform 求出仿射變換,
getRotationMatrix2D 來獲得扭轉矩陣。
這里簡單說說仿射變換是怎么做到的。
如下有兩幅圖像,圖像二是圖像一顛末放射轉變得來的。
那問題來了,我們怎么從這兩個圖像信息里挖掘出兩圖之間的映射關系?
只要在圖像一種拿出三個點(1,2,3),
圖像二也拿出對應的三個點(1,2,3),
就可以求出兩圖間的映射關系!
法式1
OpenCV經由過程兩個函數的組合利用來實現仿射變換:
利用warpAffine來實現簡單重映射
利用getRotationMatrix2D來獲得扭轉矩陣
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
//仿射變換嘗試
int main()
{
Mat src = imread("0.jpg");
Mat dst_warp, dst_warpRotateScale;
Point2f srcPoints[3];//原圖中的三點
Point2f dstPoints[3];//方針圖中的三點
//第一種仿射變換的挪用體例:三點法
//三個點對的值,只要知道變換后圖的三個點坐標,就可實現仿射變換
srcPoints[0] = Point2f(0, 0);
srcPoints[1] = Point2f(0, src.rows - 1);
srcPoints[2] = Point2f(src.cols - 1, 0);
//映射后的三個坐標值
dstPoints[0] = Point2f(0, src.rows*0.3);
dstPoints[1] = Point2f(src.cols*0.25, src.rows*0.75);
dstPoints[2] = Point2f(src.cols*0.75, src.rows*0.25);
Mat M1 = getAffineTransform(srcPoints, dstPoints);//計較變換矩陣
warpAffine(src, dst_warp, M1, src.size());//仿射變換
//第二種仿射變換的挪用體例:直接指心猿意馬角度和比例
//扭轉加縮放
Point2f center(src.cols/2, src.rows/2);//扭轉中間
double angle = 45;//逆時針扭轉45度
double scale = 0.5;//縮放比例
Mat M2 = getRotationMatrix2D(center, angle, scale);//計較扭轉加縮放的變換矩陣
warpAffine(dst_warp, dst_warpRotateScale, M2, src.size());//仿射變換
imshow("原始圖", src);
imshow("仿射變換1", dst_warp);
imshow("仿射變換2", dst_warpRotateScale);
waitKey(0);
return 0;
}
【注】:
有沒有發現圖片進行仿射變換后的布景被填充為黑色了?
其實這個布景色是可以調的,像如許:
warpAffine(dst_warp, dst_warpRotateScale, M2, src.size(), 1, 0, Scalar(11,111, 211));
//操縱Scalar來填充分歧顏色布景
法式2
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
//仿射變換嘗試
#define PIC_BEGIN_NUM 100 //這里界說你的肇端圖片編號
#define ANGLE_START -45 //扭轉角度的起頭
#define ANGLE_END 0 //扭轉角度的竣事
#define ANGLE_STEP 2 //扭轉角度步長
int main(int argc, char **argv)
{
const char* filename = "0.jpg";
Mat srcImg = imread(filename, 1);
imshow("source", srcImg);
Point center(srcImg.cols / 2, srcImg.rows / 2); //圖片中間為扭轉點
char file[20];
int count = PIC_BEGIN_NUM;
Mat tpimg;
for (int tp = ANGLE_START; tp < ANGLE_END; tp += ANGLE_STEP)
{
Mat rotMatS = getRotationMatrix2D(center, tp, 0.5); //圖片縮小到本來的0.5倍
warpAffine(srcImg, tpimg, rotMatS, srcImg.size(), 1, 0, Scalar(0, 0, 0));//填充黑色布景
sprintf(file, "%d.jpg", count++); //扭轉圖片以1.jpg 2.jpg 的名字格局保留
imwrite(file, tpimg);
}
waitKey(0);
return 0;
}
0 篇文章
如果覺得我的文章對您有用,請隨意打賞。你的支持將鼓勵我繼續創作!