我想計算紙板箱并閱讀一個特定的標簽,該標簽使用 OpenCV 和 Python 在傳送帶上僅包含 3 個白色背景的單詞。附件是我用于實驗的影像。到目前為止的問題是,由于噪聲,我無法檢測到完整的框,如果我嘗試檢查 x、y、w、h = cv2.boundingRect(cnt) 中的 w 和 h,那么它只會過濾掉文本。在這種情況下,ABC 寫在盒子上。盒子還檢測到頂部和底部都有尖峰,我不確定如何過濾。
下面是我正在使用的代碼
import cv2
# reading image
image = cv2.imread('img002.jpg')
# convert the image to grayscale format
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# apply binary thresholding
ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)
# visualize the binary image
cv2.imshow('Binary image', thresh)
# collectiong contours
contours,h = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# looping through contours
for cnt in contours:
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(image,(x,y),(x w,y h),(0,215,255),2)
cv2.imshow('img', image)
cv2.waitKey(0)
cv2.destroyAllWindows()



還請建議如何裁剪文本 ABC,然后在其上應用 OCR 來閱讀文本。
非常感謝。
編輯 2:非常感謝您的回答,根據您的建議,我更改了代碼,以便它可以檢查視頻中的框。它的作用就像一種魅力,但它只是長時間無法識別一個盒子。下面是我的代碼和我使用過的視頻的鏈接。由于我是 OpenCV 的新手,所以我有幾個問題,如果你能找到一些時間來回答的話。
import cv2
import numpy as np
from time import time as timer
def get_region(image):
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
c = max(contours, key = cv2.contourArea)
black = np.zeros((image.shape[0], image.shape[1]), np.uint8)
mask = cv2.drawContours(black,[c],0,255, -1)
return mask
cap = cv2.VideoCapture("Resources/box.mp4")
ret, frame = cap.read()
fps = 60
fps /= 1000
framerate = timer()
elapsed = int()
while(1):
start = timer()
ret, frame = cap.read()
# convert the image to grayscale format
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Performing threshold on the hue channel `hsv[:,:,0]`
thresh = cv2.threshold(hsv[:,:,0],127,255,cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]
mask = get_region(thresh)
masked_img = cv2.bitwise_and(frame, frame, mask = mask)
newImg = cv2.cvtColor(masked_img, cv2.COLOR_BGR2GRAY)
# collectiong contours
c,h = cv2.findContours(newImg, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cont_sorted = sorted(c, key=cv2.contourArea, reverse=True)[:5]
x,y,w,h = cv2.boundingRect(cont_sorted[0])
cv2.rectangle(frame,(x,y),(x w,y h),(255,0,0),5)
#cv2.imshow('frame',masked_img)
cv2.imshow('Out',frame)
if cv2.waitKey(1) & 0xFF == ord('q') or ret==False :
break
diff = timer() - start
while diff < fps:
diff = timer() - start
cap.release()
cv2.destroyAllWindows()
視頻鏈接: 
2.文本檢測:
文本區域被白色包圍,可以通過應用合適的閾值再次隔離。(您可能需要應用一些統計方法來計算閾值)
# Applying threshold at 220 on green channel of 'masked_img'
result = cv2.threshold(masked_img[:,:,1],220,255,cv2.THRESH_BINARY)[1]

筆記:
- 代碼是為共享影像撰寫的。對于不同大小的框,您可以過濾具有大約 4 個頂點/邊的輪廓。
# Function to extract rectangular contours above a certain area
def extract_rect(contours, area_threshold):
rect_contours = []
for c in contours:
if cv2.contourArea(c) > area_threshold:
perimeter = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02*perimeter, True)
if len(approx) == 4:
cv2.drawContours(image, [approx], 0, (0,255,0),2)
rect_contours.append(c)
return rect_contours
- 嘗試使用統計值(平均值、中值等)來找到檢測文本區域的最佳閾值。
uj5u.com熱心網友回復:
您的其他問題需要單獨回答:
1. 我們如何 100% 確定繪制的矩形實際上是在盒子的頂部,而不是在腰帶或其他地方?
PRO:為此,我選擇了HueHSV 顏色空間通道。灰色、白色和黑色(在傳送帶上)在這個通道中是中性的。盒子的棕色對比可以很容易地使用 Otsu 閾值分割。Otsu 的演算法無需用戶輸入即可找到最佳閾值。CON當盒子也與傳送帶顏色相同時,您可能會遇到問題
2.你能告訴我如何使用你在原始答案中提供的功能來用于這個新的視頻代碼中的其他框。
PRO:如果您想使用邊緣檢測而不使用顏色資訊來查找框;很有可能獲得許多不需要的邊緣。通過使用extract_rect()函式,您可以過濾以下輪廓:- 大約有 4 條邊(四邊形)
- 高于特定區域
CON如果您有超過 4 個面的包裹/包裹/袋子,您可能需要更改此設定。
3.再次將蒙版框架轉換為灰色,再次找到輪廓繪制矩形是否正確。或者有沒有更有效的方法來做到這一點。
我覺得這是最好的方式,因為剩下的就是用白色包圍的文本區域。應用高價值閾值是我心中最簡單的想法。可能有更好的方法:)
(我無法回答第四個問題:))
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/479043.html
