程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python-opencv 矩形框顯示不出來

編輯:Python

用Python opencv調用工業攝像頭進行幀差法進行動態跟蹤,代碼能成功運行但是矩形框畫不出來,

coding=utf-8

import cv2
import numpy as np
import mvsdk
import platform

class Camera(object):
def init(self, DevInfo):
super(Camera, self).init()
self.DevInfo = DevInfo
self.hCamera = 0
self.cap = None
self.pFrameBuffer = 0

def open(self): if self.hCamera > 0: return True # 打開相機 hCamera = 0 try: hCamera = mvsdk.CameraInit(self.DevInfo, -1, -1) except mvsdk.CameraException as e: print("CameraInit Failed({}): {}".format(e.error_code, e.message)) return False # 獲取相機特性描述 cap = mvsdk.CameraGetCapability(hCamera) # 判斷是黑白相機還是彩色相機 monoCamera = (cap.sIspCapacity.bMonoSensor != 0) # 黑白相機讓ISP直接輸出MONO數據,而不是擴展成R=G=B的24位灰度 if monoCamera: mvsdk.CameraSetIspOutFormat(hCamera, mvsdk.CAMERA_MEDIA_TYPE_MONO8) else: mvsdk.CameraSetIspOutFormat(hCamera, mvsdk.CAMERA_MEDIA_TYPE_BGR8) # 計算RGB buffer所需的大小,這裡直接按照相機的最大分辨率來分配 FrameBufferSize = cap.sResolutionRange.iWidthMax * cap.sResolutionRange.iHeightMax * (1 if monoCamera else 3) # 分配RGB buffer,用來存放ISP輸出的圖像 # 備注:從相機傳輸到PC端的是RAW數據,在PC端通過軟件ISP轉為RGB數據(如果是黑白相機就不需要轉換格式,但是ISP還有其它處理,所以也需要分配這個buffer) pFrameBuffer = mvsdk.CameraAlignMalloc(FrameBufferSize, 16) # 相機模式切換成連續采集 mvsdk.CameraSetTriggerMode(hCamera, 0) # 手動曝光,曝光時間30ms mvsdk.CameraSetAeState(hCamera, 0) mvsdk.CameraSetExposureTime(hCamera, 30 * 1000) # 讓SDK內部取圖線程開始工作 mvsdk.CameraPlay(hCamera) self.hCamera = hCamera self.pFrameBuffer = pFrameBuffer self.cap = cap return Truedef close(self): if self.hCamera > 0: mvsdk.CameraUnInit(self.hCamera) self.hCamera = 0 mvsdk.CameraAlignFree(self.pFrameBuffer) self.pFrameBuffer = 0def grab(self): # 從相機取一幀圖片 hCamera = self.hCamera pFrameBuffer = self.pFrameBuffer try: pRawData, FrameHead = mvsdk.CameraGetImageBuffer(hCamera, 200) mvsdk.CameraImageProcess(hCamera, pRawData, pFrameBuffer, FrameHead) mvsdk.CameraReleaseImageBuffer(hCamera, pRawData) # windows下取到的圖像數據是上下顛倒的,以BMP格式存放。轉換成opencv則需要上下翻轉成正的 # linux下直接輸出正的,不需要上下翻轉 if platform.system() == "Windows": mvsdk.CameraFlipFrameBuffer(pFrameBuffer, FrameHead, 1) # 此時圖片已經存儲在pFrameBuffer中,對於彩色相機pFrameBuffer=RGB數據,黑白相機pFrameBuffer=8位灰度數據 # 把pFrameBuffer轉換成opencv的圖像格式以進行後續算法處理 frame_data = (mvsdk.c_ubyte * FrameHead.uBytes).from_address(pFrameBuffer) frame = np.frombuffer(frame_data, dtype=np.uint8) frame = frame.reshape((FrameHead.iHeight, FrameHead.iWidth, 1 if FrameHead.uiMediaType == mvsdk.CAMERA_MEDIA_TYPE_MONO8 else 3)) return frame except mvsdk.CameraException as e: if e.error_code != mvsdk.CAMERA_STATUS_TIME_OUT: print("CameraGetImageBuffer failed({}): {}".format(e.error_code, e.message)) return None

def main_loop():
# 枚舉相機
DevList = mvsdk.CameraEnumerateDevice()
nDev = len(DevList)
if nDev < 1:
print("No camera was found!")
return

for i, DevInfo in enumerate(DevList): print("{}: {} {}".format(i, DevInfo.GetFriendlyName(), DevInfo.GetPortType()))cams = []for i in range(2): cam = Camera(DevList[i]) if cam.open(): cams.append(cam)while (cv2.waitKey(1) & 0xFF) != ord('q'): for cam in cams: frame = cam.grab() if frame is not None: frame = cv2.resize(frame, (640, 480), interpolation=cv2.INTER_LINEAR) frame = process_frame(frame) cv2.imshow("{} Press q to end".format(cam.DevInfo.GetFriendlyName()), frame)

def process_frame(frame):
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4)) # 返回指定形狀和尺寸的結構元素,橢圓形,中心點
kernel = np.ones((5, 5), np.uint8) # 返回矩陣
background = None
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)

# 將第一幀設置為整個輸入的背景background = gray# 對於每個從背景之後讀取的幀都會計算其與背景之間的差異,並得到一個差分圖(different map)。# 還需要應用阈值來得到一幅黑白圖像,並通過下面代碼來膨脹(dilate)圖像,從而對孔(hole)和缺陷(imperfection)進行歸一化處理diff = cv2.absdiff(background, gray)diff = cv2.threshold(diff, 148, 255, cv2.THRESH_BINARY)[ 1] # 二值化阈值處理黑白,灰度圖,對圖像進行分類的阈值,最大值,表示如果像素值大於(有時小於)阈值則要給出的值,決定給出不同類型的阈值diff = cv2.dilate(diff, es, iterations=2) # 形態學膨脹,目標圖片,進行操作的內核,默認為3×3的矩陣,腐蝕次數,默認為1# 顯示矩形框contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 該函數計算一幅圖像中目標的輪廓,只返回最外邊輪廓,# contours:返回的輪廓 hierarchy:每條輪廓對應的屬性for c in contours: if cv2.contourArea(c) < 1500: # 求得輪廓面積 對於矩形區域,只顯示大於給定阈值的輪廓,所以一些微小的變化不會顯示。對於光照不變和噪聲低的攝像頭可不設定輪廓最小尺寸的阈值 continue (x, y, w, h) = cv2.boundingRect(c)  # 該函數計算矩形的邊界框,x,y是矩陣左上點的坐標,w,h是矩陣的寬和高 cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)return frame

def main():
try:
main_loop()
finally:
cv2.destroyAllWindows()

main()


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved