<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的條形碼區(qū)域分割

          共 2064字,需瀏覽 5分鐘

           ·

          2020-10-10 03:52


          點擊上方小白學視覺”,選擇加"星標"或“置頂

          重磅干貨,第一時間送達

          本期,我們將一起學習如何從圖像中提取出含有條形碼的區(qū)域。下面的代碼,我們將在Anaconda中采用Python 2.7 完成,當然OpenCV中的圖像處理庫也是必不可少的。

          分割是識別圖像內(nèi)一個或多個對象的位置的過程。我們要介紹的技術其實非常簡單,它利用了形態(tài)算子的擴張和侵蝕以及諸如開運算,閉運算和黑帽算子的組合。

          01.簡介

          安裝Anaconda后,讓我們從Anaconda的提示符下使用以下命令轉到OpenCV安裝:

          conda install -c https://conda.anaconda.org/menpo opencv

          現(xiàn)在,讓我們從Anaconda啟動器啟動Spyder IDE。

          Anaconda啟動器

          一旦運行了Spyder,建議驗證OpenCV安裝是否成功。在Python控制臺的右下角,我們進行以下測試:

          import cv2

          代碼講解

          已經(jīng)創(chuàng)建了一個啟動GitHub存儲庫。小伙伴可以使用以下方法直接克隆它:

          git?clone?--branch?step1https://github.com/lucapiccinelli/BarcodesTutorial.git

          現(xiàn)在,我們將要下載測試圖像,并對他們進行讀取和顯示。

          測試圖片


          import cv2import?matplotlib.pyplot?as?plt
          im?=?cv2.imread(r’img\barcodes.jpg’,?cv2.IMREAD_GRAYSCALE)plt.imshow(im, cmap=’Greys_r’)

          接下來,我們將對圖像進行二值化處理,這樣可以通過閾值的設定來提取出我們感興趣的部分。使用黑帽運算符,我們可以增加較暗的圖像元素。我們可以首先使用簡單的全局閾值安全地對圖像進行二值化處理。黑帽運算符使我們可以使用非常低的閾值,而不必過多地關注噪聲。

          在應用blackhat時,我們使用的內(nèi)核會更加重視垂直圖像元素。內(nèi)核具有固定的大小,因此可以縮放圖像,這也可以提高性能(并支持某種輸入歸一化)。

          黑帽+閾值處理

          它遵循其他形態(tài)運算符的采用,順序地將它們組合在一起以獲得條形碼位置中的連接組件。

          #riscalatura dell'immaginescale = 800.0 / im.shape[1]im = cv2.resize(im, (int(im.shape[1] * scale), int(im.shape[0] * scale)))
          #blackhatkernel = np.ones((1, 3), np.uint8)im = cv2.morphologyEx(im, cv2.MORPH_BLACKHAT, kernel, anchor=(1, 0))
          #sogliaturathresh, im = cv2.threshold(im, 10, 255, cv2.THRESH_BINARY)

          膨脹和閉合的這種組合在測試圖像上效果很好,但可能無法在其他圖像上達到相同的效果。這沒有關系,大家可以嘗試改變參數(shù)和運算符的組合,直到對結果滿意為止。

          膨脹+閉運算

          最后的預處理步驟是應用具有很大內(nèi)核的開運算符,以刪除太少而無法適合條形碼形狀的元素。

          kernel = np.ones((21, 35), np.uint8)im = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel, iterations=1)

          這是我們希望得到的最終結果:

          使用35x21內(nèi)核打開

          現(xiàn)在,我們可以運行連接的組件的檢測算法,并檢索帶有坐標和尺寸的條形碼矩形。如大家在上一張圖像中所看到的那樣,最后的形態(tài)學步驟并未濾除全部的噪聲。但是,在這種情況下,將它們過濾掉非常簡單,以矩形區(qū)域值作為閾值就可以了。

          #rilettura dell'immagine, stavolta a coloriim_out = cv2.imread(r'img\barcodes.jpg')
          #estrazione dei componenti connessicontours, hierarchy = cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
          unscale = 1.0 / scaleif contours != None: for contour in contours: # se l'area non è grande a sufficienza la salto if cv2.contourArea(contour) <= 2000: continue #estraggo il rettangolo di area minima (in formato (centro_x, centro_y), (width, height), angolo) rect = cv2.minAreaRect(contour) #l'effetto della riscalatura iniziale deve essere eliminato dalle coordinate rilevate rect = \ ((int(rect[0][0] * unscale), int(rect[0][1] * unscale)), \ (int(rect[1][0] * unscale), int(rect[1][1] * unscale)), \ rect[2]) #disegno il tutto sull'immagine originale box = np.int0(cv2.cv.BoxPoints(rect)) cv2.drawContours(im_out, [box], 0, (0, 255, 0), thickness = 2) plt.imshow(im_out)#scrittura dell' immagine finalecv2.imwrite(r'img\out.png', im_out)

          最后,在上面的代碼中,我使用提取的矩形繪制它們,并將其覆蓋在原始圖像上。

          最終結果,條形碼以綠色框突出顯示。

          結論

          ? 提出的技術非常簡單有效,但存在一些令人討厭的缺點:

          ? 它對條形碼偏斜非常敏感;它可以很好地工作到大約45度,然后您必須執(zhí)行第二遍,修改內(nèi)核的方向。

          ? 它只能在固定尺寸范圍內(nèi)找到條形碼。

          ? 盡管對矩形區(qū)域施加了過濾,但仍有可能無法清除某些非條形碼。

          第一個和第二個可能不是真正的問題,但是最后一個可能會花費大家大量時間來嘗試解碼非條形碼的內(nèi)容。

          一個很好的解決方案是將條形碼特征(圖像梯度,傅立葉變換)輸入給神經(jīng)網(wǎng)絡(或一些其他一些分類器),并在第二時刻過濾掉噪聲。

          下面給出完整的示例代碼。

          import cv2import matplotlib.pyplot as pltimport numpy as np
          im = cv2.imread(r'img\barcodes.jpg', cv2.IMREAD_GRAYSCALE)im_out = cv2.imread(r'img\barcodes.jpg')
          #riscalatura dell'immaginescale = 800.0 / im.shape[1]im = cv2.resize(im, (int(im.shape[1] * scale), int(im.shape[0] * scale)))
          #blackhatkernel = np.ones((1, 3), np.uint8)im = cv2.morphologyEx(im, cv2.MORPH_BLACKHAT, kernel, anchor=(1, 0))
          #sogliaturathresh, im = cv2.threshold(im, 10, 255, cv2.THRESH_BINARY)
          #operazioni morfologichekernel = np.ones((1, 5), np.uint8)im = cv2.morphologyEx(im, cv2.MORPH_DILATE, kernel, anchor=(2, 0), iterations=2) #dilatazioneim = cv2.morphologyEx(im, cv2.MORPH_CLOSE, kernel, anchor=(2, 0), iterations=2) #chiusura
          kernel = np.ones((21, 35), np.uint8)im = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel, iterations=1)
          #estrazione dei componenti connessicontours, hierarchy = cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
          unscale = 1.0 / scaleif contours != None: for contour in contours: # se l'area non è grande a sufficienza la salto if cv2.contourArea(contour) <= 2000: continue #estraggo il rettangolo di area minima (in formato (centro_x, centro_y), (width, height), angolo) rect = cv2.minAreaRect(contour) #l'effetto della riscalatura iniziale deve essere eliminato dalle coordinate rilevate rect = \ ((int(rect[0][0] * unscale), int(rect[0][1] * unscale)), \ (int(rect[1][0] * unscale), int(rect[1][1] * unscale)), \ rect[2]) #disegno il tutto sull'immagine originale box = np.int0(cv2.cv.BoxPoints(rect)) cv2.drawContours(im_out, [box], 0, (0, 255, 0), thickness = 2) plt.imshow(im_out)#scrittura dell' immagine finalecv2.imwrite(r'img\out.png', im_out)

          交流群


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


          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  久久99精品久久久水蜜桃 | 人人草人人插 | 亚洲黄色免费大全 | 2019天天干天天色 | 中文字幕欧美风情 |