使用 Python OpenCV 将实时视频流中检测到的二维码保存为图像



我正在开发一个使用 Python(3.7( 和 OpenCV 2 的项目,其中我必须检测二维码并将其另存为图像,我已经成功完成了检测部分,但不知道如何将二维码保存为图像?

这是我到目前为止尝试过的:

代码的检测部分:

while True:
frame = vs.read()
frame = imutils.resize(frame, width=400)
barcodes = pyzbar.decode(frame)
for barcode in barcodes:
(x, y, w, h) = barcode.rect
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
text = "{}".format(barcodeData)
cv2.putText(frame, '', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
if barcodeData not in found:
csv.write("{}n".format(barcodeData))
csv.flush()
found.clear()
found.add(barcodeData)
# Título do Frame
cv2.imshow("Live Stream Window", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break

如何将检测到的区域(二维码(保存为图像?

更新:以下是自动更新的 svae 图像的更新代码,但这不起作用。

while True:
frame = vs.read()
frame = imutils.resize(frame, width=400)
original = frame.copy()
barcodes = pyzbar.decode(frame)
barcode_num = 0
frame_dict = {'y': 0, 'w': 0, 'h': 0, 'x': 0}
for barcode in barcodes:
(x, y, w, h) = barcode.rect
print(f'{x}, {y}, {w}, {h}')
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
ROI = original[y:y + h, x:x + w]
frame_dict['y'] = y
frame_dict['x'] = x
frame_dict['h'] = h
frame_dict['w'] = w
barcode_num += 1
barcodeData = barcode.data.decode("utf-8")
print(barcodeData)
barcodeType = barcode.type
text = "{}".format(barcodeData)
cv2.putText(frame, '', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
if barcodeData not in found:
csv.write("{}n".format(barcodeData))
csv.flush()
found.clear()
found.add(barcodeData)
cv2.imshow("Live Stream Window", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("c"):
print('c is pressed')
ROI = original[frame_dict['y']:frame_dict['y'] + frame_dict['h'],
frame_dict['x']:frame_dict['x'] + frame_dict['w']]
cv2.imwrite('barcode_{}.png'.format(barcode_num), ROI)
pass
if key == ord("q"):
break

假设(x, y, w, h) = barcode.rect返回与x,y,w,h = cv2.boundingRect(contour)相同的值,下面是从图像中裁剪 ROI 的可视化

效果
-------------------------------------------
|                                         | 
|    (x1, y1)                             |
|      ------------------------           |
|      |                      |           |
|      |                      |           | 
|      |         ROI          |           |  
|      |                      |           |   
|      |                      |           |   
|      |                      |           |       
|      ------------------------           |   
|                           (x2, y2)      |    
|                                         |             
|                                         |             
|                                         |             
-------------------------------------------

(0,0)视为图像的左上角,从左到右作为 x 方向,从上到下作为 y 方向。如果我们(x1,y1)作为 ROI 的左上角,(x2,y2)作为右下角的顶点,我们可以使用 Numpy 切片来裁剪图像:

ROI = image[y1:y2, x1:x2]

但通常我们不会有右下角的顶点。在典型情况下,我们将遍历轮廓,其中矩形 ROI 坐标可以用cv2.boundingRect()找到。此外,如果我们想节省多个ROI,我们可以保留一个计数器

cnts = cv2.findContours(grayscale_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
ROI_number = 0
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+w]
cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
ROI_number += 1

回到你的问题,这是我们可以做到的。请注意,我们original = frame.copy()复制框架,因为一旦我们使用cv2.rectangle在图像上绘制,它将绘制到框架上。当我们裁剪它时,我们不想要这个涂漆的框架,所以我们从框架的副本中裁剪。

while True:
frame = vs.read()
frame = imutils.resize(frame, width=400)
original = frame.copy()
barcodes = pyzbar.decode(frame)
barcode_num = 0
for barcode in barcodes:
(x, y, w, h) = barcode.rect
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
ROI = original[y:y+h, x:x+w]
cv2.imwrite('barcode_{}.png'.format(barcode_num), ROI)
barcode_num += 1
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
text = "{}".format(barcodeData)
cv2.putText(frame, '', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
if barcodeData not in found:
csv.write("{}n".format(barcodeData))
csv.flush()
found.clear()
found.add(barcodeData)
# Título do Frame
cv2.imshow("Live Stream Window", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break

最新更新