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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python正十三边形_一起学python-opencv十三(直方图反向投影和模板匹配)

發布時間:2023/12/4 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python正十三边形_一起学python-opencv十三(直方图反向投影和模板匹配) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2D直方圖

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_histograms/py_2d_histogram/py_2d_histogram.html#twod-histogram

為什么只考慮h,s就夠了呢?

因為其實亮度是很容易受外界影響的,我們認為一個顏色的本質特征是h和s。計算2D直方圖,我們用的還是calcHist函數,不過參數得輸入兩個通道的了。H原來是0-360,為了讓8位能存下,就對應到了0-180。第四個參數是[xmin,xmax,ymin,ymax]這種形式的。x指的是行,y指的是列。

bins上面有很多規則,請大家大概看一下,說的是如果是一個int,那么兩個維度區間的數目都是int,如果是[int,int]這個兩個分別是兩個維度的bins個數,還有其它規則請自行查看。上面給出了range的格式[[xmin,xmax],[ymin,ymax]]。

返回的H是二維的直方圖分布,xedges是第一個維度的區間邊界組成的數組,yedges是第二個維度的。

上面應該是少了一句h,s,v=cv2.split(hsv)。下面是如何畫直方圖:

這個是可以大概看一下,越白的地方數值越高。其實有點像等高圖,不過我們這里最低是黑色,而不是藍色。還有就是用matpltlib畫圖了:

還參考了https://blog.csdn.net/goldxwang/article/details/76855200

imshow里的interpolation參數是插值的意思,為什么需要插值呢?因為我們的hist只提供了整數點的值而沒有提供中間的值,那么這些值該怎么補充呢?這時候就需要用到插值。

插值方式有很多種,上面有列出來。blinear是雙線性插值。這個我們前面介紹過,還有一個nearest也很常用。參考了https://blog.csdn.net/ccblogger/article/details/72918354

這里是舉了一個例子:

默認用的應該就是這種插值,需要注意的是,最近鄰插值是還要四舍五入的。

當然計算機也不可能一個點一個點去算,那也是無數個點,肯定有一個最小單位。旁邊的這個類似于等高圖高度顏色帶的這個東西是colorbar生成的,plt.colorbar()要寫在plt.show()之前。

這里需要注意一下:

596*300=238400。

去掉中括號以后就不對了。和不知道為什么是800。

用np生成二維直方圖也是可以的,結果是一樣的。

減小分的區間數的話。圖看起來更明顯一些。

需要提醒的是左下角是可以看到對應的高度值的:

[4.02e+04]就是鼠標所在處的高度。

直方圖反投影

原理介紹:參考了https://blog.csdn.net/zyzhangyue/article/details/45827261

這個是一個滑動窗口,每次移動一個像素,然后計算窗口中圖像的直方圖和模板直方圖的相似度。

最后肯定是要閾值化的,相似度大于某一個值才認為是我們要的結果。

函數實現:

中間最重要的函數當然是calcBackProject了。

scale是比例。我來選一個模板,就是圈起來的那朵花。

大概在[34:73,234:263]這個范圍。

出來的dst就是如果和模板直方圖越接近(這個接近可能就是用的直方圖比較中的某一種距離來度量)結果數值越大,那么用灰度顯示也就會越白,當然我猜測這個函數里面是還有一些處理的,因為滑動窗口每次只滑動一個像素嘛,有很多像素就重合了,那么這些像素點的輸出值怎么辦呢?我猜想可能就是取平均了。注意中括號。

模板直方圖分的區間越少,也就是分的越粗,直方圖反投影得到的結果越連續,但是也能太大。20的效果還算不錯。

下面就分得太粗略了。

分得太細比較難匹配到。

我有點不懂為什么上面要對模板直方圖歸一化。alpha是歸一化范圍的下限,而beta是上限,normal_type是歸一化方法,有很多種,參考了:https://www.cnblogs.com/sddai/p/6250094.html

我們常用的是:

我試了一下,好像有點知道是個怎么回事了。

這個模板直方圖的歸一化的最大值好像和輸出的dst的最大值是一樣的,當300的話就是飽和的,會被認為是255,雖然不知道為什么有這樣的設定,這個得深究到下面的c++代碼了。我前面不加為什么可以呢?因為我選擇的模板直方圖的最大值271大于255。這算是一個巧合,是因為我選擇的模板圖像比較大,然后顏色又都比較偏白色。那么這個歸一化的語句最好還是加上去吧。

596*400和我們的原圖形狀是一樣的。

最終輸出的圖像其實有點不太理想,我們把它再閾值化一下,當然這個閾值該怎么選,這個需要自己測試。中間的那個cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))是一種形態學處理,我們先不管它。閾值操作:

0其實就代表的是表格中的第一種閾值化方式:

效果還不錯。把這個和原圖與一下。

我選的這個模板有點太白了,不太明顯。

我前面也說過,直方圖不能代表圖像的全部信息,因為它只包含強度信息,缺少了位置信息,所以上面匹配到的結果其實還是有很多不是我們想要的。下面是一種考慮了位置信息的匹配方式。

模板匹配

原理:模板匹配的原理其實很簡單,還是基于滑動窗口,一個像素一個像素的去移動,只不過上面我們計算的是圖像直方圖的相似度,我們這里是直接計算圖像的相似度,方法有好多種,參考了

https://blog.csdn.net/tsvico/article/details/78817096

計算起來其實挺麻煩的,有的時候我們就需要用到一些比較巧的辦法,比如說對于一些相乘項的求和,我們或許可以把其中一個調轉180,這個是為了湊成卷積的形式,然后根據卷積定理轉到頻域去計算離散的傅里葉變換相乘,然后再傅里葉反變換回來,這樣是會減小計算量的。

還有一種加快運算速度的方法叫做積分圖法。參考了

https://blog.csdn.net/yuan1125/article/details/70274515

就是從左上角開始累積像素值,最后生成一個圖,就叫積分圖。

一個區域的特征值就是這個區域里所有像素點對應強度的和。

上面原理和如何加快計算的方法,下面就是代碼的實驗了。

為什么輸出圖像的大小會變小呢?這是因為輸出的圖像其實是由上面的方法計算出來的相似度,輸出的結果其實只需要取從左上角開始取(W-w+1,H-h+1)就夠了,因為剩下的區域是不可能作為匹配區域的左上角的,因為不夠啊。為什么取左上角,因為底層的c++是這么寫的。

紅色代表目標圖片,藍色是模板圖片,紅色是輸出區域。

官方例子是個灰度圖像,shape[::-1是步長為-1,為什么要為-1呢?這是因為w寬度,也就是列數和h高度,行數的位置是反過來的,我們完全可以寫h,w=template.shape。官方也是有點皮。我們還是匹配那朵白玫瑰。我先來介紹幾個函數,首先是模板匹配的函數:

這里面的參數的英文單詞很常見了。templ是模板的意思。

這個函數是找出最大值,最小值以及對應的位置。上面這些比較方法應該都在c++里面由宏定義的。eval就是為了去掉引號,那一開始在method列表里面別加引號不就行了嗎?搞不懂。

plt.xticks是選x軸坐標刻度的,他這樣寫就是不要刻度。plt.suptitle是大標題,因為有幾個子圖嘛,所以會有一個大標題咯。我就改了四處。

400-29+1=372,598-38+1=559。

如果把xTicks和yTick里刪掉,那么就會有刻度了。這個第一種方法結果稍微有點不對。

這其實和模板匹配算法有關系,下面其實寫錯了,我畫紅線的話都是錯的,不用在意。

這種方法取的是應該是左圖中最亮的地方。那么這樣的算法為什么不是一樣的最大呢?

設想黑線是均值,然后紅色是模板,藍色是我設定的圖像,那么你說按照上面的公式是紅色和紅色的值大,還是紅色和藍色的值大呢?毫無疑問是紅色和藍色。上面的方法是判斷相關性的而不是相似性,所謂相關性就是你增大,我也增大,你減小我也減小,那么我們就叫做正相關,反之叫做負相關,和增大和減小前的值和增大或者減小了多少都無關,所以說這個模板匹配方法很不好。

這個匹配的是對的。也是取左圖中最亮的地方。這種方法才是1代表正相關,-1代表負相關,0代表線性無關。

為什么標準相關匹配結果就可以呢?我想用柯西不等式來說明問題

-1<=R(x,y)<=1,這個取等條件比較苛刻,是所有位置對應像素的強度成比例才可以,一般這種條件在圖像中也就是同一張圖才能達到這樣的條件了,至少在我們這張圖上是的。

這個也是取最亮的地方,也是稍微有一點偏差的。

這個匹配的結果也還好。

上面兩種方法的差別和上面的相似,只不過上面是減去了絕對值,這里沒有減去絕對值而已,還是用相關性不是相似度和柯西不等式來解釋。

這個是找最暗的。匹配的也不錯。

上面兩個是做差后平方和的結果,當然是同一張圖片的輸出區域最暗了。對于我們這張圖,六種里面四種匹配的都還不錯,但是都是有一些條件的,不過我覺得沒有標準化的那兩個相關性方法就不要用了,比較差。

一個模板匹配多個對象

這個不只是取一個最大的或者最小的了,而是規定一個閾值,這個閾值時自己設定的,可以找到多個對象。我們還是用上面的來做實驗。

閾值設為0.8也還是只能匹配到我們的原圖。

0.5的時候又出現一個新的區域。

0.45的時候就比較多了。

這里還要提醒一點,plt.imshow單通道的時候,選擇cmap='gray',也就是顏色圖取的是灰度圖才會和cv2顯示的一致。不然用的時它使用的不是灰度系統。

用的時什么image.cmap。不知道這是個什么東西,但是絕對不是灰度。如果時3維就沒事,因為它會直接用RGB。

沒使用灰度之前。

之后:

雖然不知道為什么顯示的一個黑一個白。

不過好歹時回到了灰度空間。我有點理解為什么全是黑的了。首先colorbar會讓plt.imshow按照我們的灰度值來。注釋了colorbar后:

不注釋:

感覺其實挺奇怪的,我的理解是plt.imshow單通道的時候必須要有一個對比才行,如果全是一種顏色,colorbar也算是一種對比的手段,這個時候顯示的是完美的按照灰度。如果不是一個值,顯示的是相對灰度,也就是里面的最大值就是白色,最小值是黑色,線性插值來顯示灰度值。

前面又出現了變量前加*號的操作。

這個以前其實也說過的,不過相信很多人都忘了,其實也包括我,233,這很符合遺忘規律嘛,忘了不要緊,復習一下:https://zhidao.baidu.com/question/2140001532025683868.html

那這里為什么還要反著來呢?其實很簡單了,這個其實是用rectangle畫畫的一個特性:

這個實驗我們可以看到,rectangle里面傳遞參數的時候是列在前的,行在后的,這可能是為了適應我們的x軸水平,y軸垂直,一般寫坐標都是(x,y)這樣的習慣。不過這和np的格式就反過來了,因為np是行在前,列在后。還有一點需要注意:頂點坐標必須是元組。

好的,馬上是十一了,但是休息是不可能休息的。

總結

以上是生活随笔為你收集整理的python正十三边形_一起学python-opencv十三(直方图反向投影和模板匹配)的全部內容,希望文章能夠幫你解決所遇到的問題。

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