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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

如何将图片中的一个任意四边形区域的图像转化为矩形【附源码】

發布時間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何将图片中的一个任意四边形区域的图像转化为矩形【附源码】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
將一幅圖像中的任意四邊形區域映射為矩形區域。比如,我們有時拍照片,因為角度的問題,本來是矩形的廣告牌,在照片中可能表現為一個任意的四邊形。事實上,在現實中本來是矩形的物體,在照片中往往呈現為任意四邊形,因此很多情況下有必要將. 這些任意四邊形變換回矩形。將任意四邊形的圖片轉化為矩形的應用現在在我們身邊也時常見到## 標題:安卓端的adobe reader最近(2017年)新推出的掃描功能,因為拍照片時不可能完全正對我們的文檔,就包含了該功能;同期,WPS office 也推出了掃描功能;除此之外,當我們掃描二維碼時,也可以利用該變換,來實現對傾斜拍攝的圖片進行掃碼。該映射學術名稱為中心投影變換,Perspective Mapping。先來看一個示例:(示例只是為了給大家一個直觀的理解,所以并沒有實現非常精確的變換)

-----------------------------------------------------分割線-----------------------------------------------------------

這是源圖,我們的目的是把里邊的顯示屏顯示的部分提取出來,并且映射回矩形

圖1. 源圖

這是處理后的效果圖

圖2. 效果圖

看了這兩張圖,大家應該知道算法的目的了。

-----------------------------------------------------分割線-----------------------------------------------------------

原文地址:https://www.geometrictools.com/Documentation/PerspectiveMappings.pdf

建議大家看英文原文,根據里邊的公式進行推導。

先直接上原理圖,大家才好有一個直觀的認識

圖3. 中心投影變換原理圖 (a) 中心投影變換圖示 (b)任意四邊形 ?矩形

假設E點是發光源,任意四邊形 q00 q01 q11 q10 可以在一個平面上投影為 r00 r01 r11 r10 。如圖3(a)所示。q00投影為r00,q01投影為r01,q11投影為r11,q10投影為r10。根據線性代數的知識,只要知道了圖3(a)中的各個頂點的坐標,那么可以很簡單地將任意四邊形中的q點映射到矩形中的r點,并計算出其坐標。接下來我們嘗試找到q到r或者r到q的映射關系。

注:

1) q是quadrilaterals(四邊形)的第一個字母,r是rectangle(矩形)的第一個字母;

2) 為了簡化問題,我們將q00和r00重合為一點,設為o點;

3) 可以證明,一個任意四邊形在圖3(a)的投影方式下一定可以投影為矩形,后面的算法分析過程可以證明這一點。事實上還可以證明,r點和q點的坐標變換公式與E點的位置無關。

問題轉化為將圖3(b)中的任意四邊形變換為圖3?中的矩形。?中的矩形是很容易“放”到(a)中,至少這個過程能夠比較直觀地想象出來。但是將(b)中的任意四邊形“放"到(a)中,這個過程可能不容易想象。接下來我們用線性代數或者高中學的空間幾何知識來模型化這個過程。

事實上,我們只需要將(b)中的任意四邊形Q00 Q01 Q11 Q10映射到(a)中的任意四邊形q00 q01q11 q10,將?中的矩形R00 R01 R11 R10映射到(a)中的矩形r00 r01 r11 r10,然后根據r到q的映射關系,就能解決該問題了。

進下來進入公式推導環節。為了和原文一致,建立以下坐標系

注:將矩形的四個頂點定義為o, (1 0 0), (0 1 0), (1 1 0)并不影響結果,即便此時它是正方形。原因是,我們關心的是任意點r的坐標由向量or10和向量or01線性組合時的系數,即

r = x0r10 + x1r01 (1)

所以無論坐標系怎么設置,x0和x1的值并不會變,即長方形和正方形原理是一樣的。

注:r表示or向量,r10表示or10向量,下文也是同樣的標注方式,以加粗的方式表示向量。

為了讓q00(o點) q01 q11 q10四點共面,最好的方法就是將向量oq11 表示為向量 oq01 和向量 oq10的線性組合,記為

q11 = a0q10 + a1q01 (2)

只要任意四邊形給定,a0和a1兩個值可以直接求出,因此可以看作是常量。

同樣,任意四邊形中的任意一點q可以表示為

q = y0q10 + y1q01 (3)

因為點E,q,r三點共線,所以r點的坐標可以表示為

r = E + t(q-E) (4)

注:這是高中線性代數相關知識。

其中t為乘法系數

因此可以得到以下四個方程

r00 = (0,0,0) = E + t00(q00 -E) (5)

r10 = (1,0,0) = E + t10(q10 - E) (6)

r01 = (0,1,0) = E + t01(q01 - E) (7)

r11 = (1,1,0) = E + t11(q11 - E) (8)

易知,t00 = 1

假設平面oq01q11q10存在法向量N,則上面四個方程左邊右邊同時點乘N(n0,n1,n2),可得

(1-t10)N·E = n0, (1-t01)N·E = n1, (1-t11)N·E = n0+n1;

將前兩個等式等號左邊部分相加,與第三個等式比較,發現等號右邊都為n0+n1, 因此左邊也應該相等,得:

t11 = t10 + t01 -1 (9)

結合公式(9)與(2),(5),(6),(7),(8)可以解出t00,t10,t01,t11,得到

t00 = 1, t10 = a0 / (a0+a1-1), t01 = a1 / (a0+a1-1), t11 = 1 / (a0+a1-1) (10)

注:a0和a1理解為常數,因為一旦任意四邊形確定,a0和a1可以馬上算出來,體現在matlab中就是一個矩陣左除運算。

根據公式

(1) r = x0r10 + x1r01

(3) q = y0q10 + y1q01

(4) r = E + t(q-E)

將(1)(3)帶入(4),并將r表示為(x0,x1,0),可得

(x0, x1, 0) = E + t(q - E) =E + t(y0q10 + y1q01 - E) (11)

根據公式(6),(7)以及已經計算出來的r00,t10,t01,t11值,可以將q10和q01用E和(1,0,0)和(0,1,0)表示出來,然后帶入公式(11),可得

E和(1,0,0)和(0,1,0)三個向量線性無關,而他們的線性組合等于0向量,所以三個系數必須都為0(線性代數中的定理)。于是得到

該公式的物理意義如下:

1)知道了矩形區域內的一個像素點的坐標,假設為(height,width) = (100,100),同時假設我們想要輸出的矩形圖像的大小為200300(即heightwidth),那么x0為1/2,x1為1/3;也就是說x0和x1是將矩形視為單位正方形的情況下時,點的坐標。這也是上面的分析過程中可以用單位長度的正方形來表示矩形的原因。

2)對于任意四邊形中的一個點,y1的值類似地理解,只不過這時候的基向量不再相互垂直,可以在matlab中用左除矩陣的方式很快地求出這兩個值。

3)該公式可以完成這樣一種功能:假如需要找到矩形中一個點對應的任意四邊形中的點,我們可以求出該點對應的x0,x1的值,然后通過該公式找到y0和y1的值,再利用y0和y1和公式(3),找到任意四邊形中一個具體的點的坐標。

注:在任意四邊形中找到的具體坐標通常不是整數,所以需要采用一定的插值策略,下面的代碼中用的最近鄰域插值。采用其他高級插值方式可能效果更好,不過這不是本文的中心,本文不討論。

同時,我們也可以找到反變換,物理意義同上。

以下是matlab源碼

注:這只是核心函數,外圍測試函數請參考我下面給出的鏈接中的資源。

%函數功能:中心投影變換。輸入源圖,源圖中的任意四邊形的4個點的坐標(左上,右上,左下,右下),對應于上面示例圖中顯示器四個角在源圖中的四個坐標點,以及輸出圖像的大小(高,寬)。注意四個點的順序不是左上,右上,右下,左下。如果有必要,請自行調整順序。

%例如 imgBack = m_PerspectiveTransformation(imgSrc,[831 1542],[275 3096],[1727 1394],[1601 3151],900,1600);
function Imgback = m_PerspectiveTransformation(imgIn,pointLT,pointRT,pointLB,pointRB,outHeitht,outWidth)
[imgInHeight,imgInWidth,imgInDimension] = size(imgIn);
%為了中心投影變換,需要將4個點轉化為三個向量,具體看參考文獻
vector10 = pointLB - pointLT;
vector01 = pointRT - pointLT;
vector11 = pointRB - pointLT;
%把vector11表示成vector10和vector01的線性組合,以使三個向量共面
A = [vector10’ , vector01’];
B = vector11’ ;
S = A\B;
a0 = S(1);
a1 = S(2);

%初始化輸出矩形 Imgback = uint8(zeros(outHeitht,outWidth,imgInDimension));%利用循環操作來對每個像素點賦值 for heightLoop = 1:outHeithtfor widthLoop = 1:outWidth%以下算法為參考文獻中的公式表示x0 = heightLoop/outHeitht;x1 = widthLoop/outWidth;FenMu = a0+a1-1+(1-a1)*x0+(1-a0)*x1; %分母y0 = a0*x0/FenMu;y1 = a1*x1/FenMu;%根據得到的參數找到對應的源圖像中的坐標位置,并賦值coordInOri = y0*vector10 + y1*vector01 + pointLT;heightC = round(coordInOri(1));widthC = round(coordInOri(2));if (heightC > imgInHeight || heightC <= 0 || widthC >imgInWidth || widthC <=0 )disp(['m_PerspectiveTransformation超出范圍' num2str(heightC) num2str(widthC)]);pause();return;endfor dimentionLoop = 1:imgInDimension%使用最近鄰域插值。使用高級插值方法效果可能會更好Imgback(heightLoop,widthLoop,dimentionLoop) = imgIn(heightC,widthC,dimentionLoop);endend end

% figure; imshow(Imgback); title(‘投影變換的結果’);

示例程序可以在這里下載(matlab代碼)

https://download.csdn.net/download/u014495306/9892055

總結

以上是生活随笔為你收集整理的如何将图片中的一个任意四边形区域的图像转化为矩形【附源码】的全部內容,希望文章能夠幫你解決所遇到的問題。

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