<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          詳解OpenCV卷積濾波之邊緣處理與錨定輸出

          共 6115字,需瀏覽 13分鐘

           ·

          2021-06-24 19:21

          點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時間送達(dá)

          本文轉(zhuǎn)自|OpenCV學(xué)堂

          概述

          OpenCV在使用卷積進(jìn)行圖像處理過程種,如何處理邊緣像素錨定輸出兩個技術(shù)細(xì)節(jié)一直是很多人求而不得的疑惑。其實OpenCV在做卷積濾波時會對圖像進(jìn)行邊界填充,實現(xiàn)對邊緣像素的卷積計算的支持,不同填充方式不同錨定點(diǎn)會得到圖像卷積輸出不同的結(jié)果。

          邊界填充

          我們首先來看一下OpenCV種支持標(biāo)準(zhǔn)卷積邊緣填充做法,OpenCV支持的有如下幾種卷積邊緣填充算法:

          常量邊界

          BORDER_CONSTANT

          iiiiii|abcdefgh|iiiiiii

           

          邊界復(fù)制

          BORDER_REPLICATE

          aaaaaa|abcdefgh|hhhhhhh

           

          邊界反射

          BORDER_REFLECT

          fedcba|abcdefgh|hgfedcb

           

          邊界換行

          BORDER_WRAP

          cdefgh|abcdefgh|abcdefg

           

          邊界反射101

          BORDER_REFLECT_101

          gfedcb|abcdefgh|gfedcba

           

          邊界透明-很不幸運(yùn)的是OpenCV4已經(jīng)不支持啦!

          BORDER_TRANSPARENT

          uvwxyz|abcdefgh|ijklmno

           

          默認(rèn)填充方式

          OpenCV中 filter2D, blur, GaussianBlur等卷積操作默認(rèn)支持為BORDER_DEFAULT(BORDER_REFLECT_101)


          各種不同方式對邊緣的填充效果如下:

          上圖背景為紅色,填充上下左右四個像素大小邊緣!右下角為原圖,左上角圖像為常量邊緣填充效果(i=0黑色)。

           

          相關(guān)代碼實現(xiàn)如下:

          image = cv.imread("D:/images/qxx.png");
          ih, iw = image.shape[:2]
          border = 4

          # 邊界填充
          b1 = cv.copyMakeBorder(image, border, border, border, border, cv.BORDER_CONSTANT)
          b2 = cv.copyMakeBorder(image, border, border, border, border, cv.BORDER_REPLICATE)
          b3 = cv.copyMakeBorder(image, border, border, border, border, cv.BORDER_REFLECT)
          b4 = cv.copyMakeBorder(image, border, border, border, border, cv.BORDER_WRAP)
          b5 = cv.copyMakeBorder(image, border, border, border, border, cv.BORDER_REFLECT_101)

          # 邊界填充類型說明
          cv.putText(image, "input", (20,20), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))
          cv.putText(b1, "BORDER_CONSTANT", (2020), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))
          cv.putText(b2, "BORDER_REPLICATE", (2020), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))
          cv.putText(b3, "BORDER_REFLECT", (2020), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))
          cv.putText(b4, "BORDER_WRAP", (2020), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))
          cv.putText(b5, "BORDER_REFLECT_101", (2020), cv.FONT_HERSHEY_PLAIN, 1.0, (25500))

          # 拼接結(jié)果輸出
          h = b1.shape[0]*2+8
          w = b1.shape[1]*3+16
          bh, bw = b1.shape[:2]
          result = np.zeros([h, w, 3], dtype=np.uint8)
          result[:,:,:] = (00255)
          result[0:bh,0:bw,:] = b1;
          result[0:bh, bw+8:bw+bw+8, :] = b2;
          result[0:bh, bw+bw+16:bw+bw+bw+16, :] = b3;
          result[bh+8:bh+bh+8,0:bw,:] = b4;
          result[bh+8:bh+bh+8, bw+8:bw+bw+8, :] = b5;
          result[bh+12:bh+12+ih, bw+bw+20:bw+bw+20+iw, :] = image;

          # 顯示
          cv.imshow("result", result)
          cv.imwrite("D:/border_result.png", result)
          cv.waitKey(0)
          cv.destroyAllWindows()


          錨定位置

          在進(jìn)行卷積處理的時候,卷積mask與對應(yīng)的像素塊點(diǎn)乘得到輸出,把輸出結(jié)果賦值給哪個像素點(diǎn)是由錨定參數(shù)anchor決定,以自定義濾波函數(shù)filter2D為例說明

          void cv::filter2D(
                   InputArray src,
                   OutputArray dst,
                   int ddepth,
                   InputArray      kernel,
                   Point       anchor = Point(-1,-1),
                   double    delta = 0,
                   int borderType = BORDER_DEFAULT
          )
          其中
          kernel - 表示輸入的自定義卷積核大小
          anchor - 表示錨定點(diǎn)位置,默認(rèn)情況Point(-1-1)表示是卷積核的中心位置
          borderType - 表示邊緣填充的像素大小,ksize/2其中ksize表示卷積核大小


          上述函數(shù)在卷積核為奇數(shù)的時候,卷積核的中心位置很容易確定,比如3x3的卷積核大小,中心位置為Point(1,1),5x5的卷積核大小中心位置為Point(2,2)


           

          但是當(dāng)卷積核大小為偶數(shù)的時候,很多人都搞不清楚中心位置是如何確定的,其實這個時候中心也為(ksize/2), 對2x2的卷積核,中心位置為Point(1,1),4x4的卷積核中心位置為Point(2,2)。

          錨定位置對卷積結(jié)果的影響

          以2x2與4x4的卷積核為與3x3與5x5的像素數(shù)據(jù)為例


          情況一

          2x2卷積核對3x3的像素塊

          當(dāng)錨定點(diǎn)為默認(rèn)(1,1)/(-1,-1)時候:

          當(dāng)錨定點(diǎn)設(shè)置為(0,0)時:

          可以看到二者的輸出結(jié)果全然不同,原因在于當(dāng)錨定點(diǎn)不同的時候,卷積mask的開始位置也會不不同,圖示如下:

          情況二:

          4x4卷積核對5x5的像素塊:

          使用BORDER_DEFAULT填充方式,填充之后為:

          不同錨定位置的均值卷積輸出結(jié)果:

          三個不同錨定點(diǎn)對應(yīng)卷積mask的起始位置與錨定像素輸出:

          代碼演示如下:

          src = np.zeros([33], dtype=np.uint8)
          src[00] = 16
          src[11] = 8
          src[22] = 4
          print("\n input image: \n",src)

          k1 = [[10], [0-1]]
          print("\nkernel : \n", k1)
          result = cv.copyMakeBorder(src, 1111, cv.BORDER_DEFAULT)
          print("\nBORDER_DEFAULT 邊界填充 : \n", result)
          dst = cv.filter2D(src, cv.CV_32F, np.asarray(k1), None, anchor=(00), borderType=cv.BORDER_DEFAULT)
          print("\nfilter2D : \n", dst)
          print("\n")

          src = np.zeros([55], dtype=np.uint8)
          src[00] = 32
          src[11] = 16
          src[22] = 8
          src[33] = 4
          src[44] = 2
          print("\ninput: \n", src)
          k2 = np.ones([44], dtype=np.int32)
          print("\nkernel:\n", k2)
          result = cv.copyMakeBorder(src, 3333, cv.BORDER_DEFAULT)
          print("\n邊界填充:\n", result)
          dst = cv.filter2D(src, cv.CV_32F, np.asarray(k2), None, anchor=(-1-1), borderType=cv.BORDER_DEFAULT)
          print("\n filter2D Result: \n", dst)


          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實戰(zhàn)項目52講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實戰(zhàn)項目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機(jī)視覺。

          下載3:OpenCV實戰(zhàn)項目20講
          小白學(xué)視覺公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人乱码视频欧美 | 九九热这里只有精品12 | 午夜1级操逼视频 | 网红操逼视频在线观看免费视频在线观看 | 欧美在线 | 亚洲 |