python中

时间:2015-09-05 15:07:18

标签: python opencv image-processing opencv3.0

我正在使用背景减法来分析室外场景的移动物体。当太阳出来时我有阴影问题。我正在使用轮廓来隔离对象。目前我只是分析轮廓的上半部分,因为阴影通常位于下半部分。

想象一下橡皮鸭的轮廓,我想要做的是找到鸭子颈部的y位置,即轮廓处于最小水平尺寸的位置。 有人可以指点我如何找到“鸭脖子”的正确方向吗?

enter image description here

在代码中,binary是移动对象的阈值图像,HIGHTWIDTH是图像的高度和宽度,lab是相同的图像在LAB颜色空间中。

我想用一个函数替换half = int(h/2)行来找到水平线的y位置以切断“鸭脖”。

_,contours,_ = cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)

# loop over the contours
for i, cnt in enumerate(contours):

   # compute the bounding box for the contour
   (x, y, w, h) = cv2.boundingRect(cnt)

   # reject contours outside size range
   if w > 250 or w < 30 or h > 250 or h < 30 :
          continue

   # make sure the box is inside the frame
   if x <= 0 or y <= 0 or x+w >= (WIDTH -1) or y+h >= (HIGHT -1):
          continue

   # isolate feature
   half = int(h/2)
   roi = lab[y:y+half, x:x+w]
   mask = binary[y:y+half, x:x+w]

   # calculate the mean of the colour
   mean = cv2.mean(roi, mask = mask)
   # note: mean is L a b
   L = int(mean[0])
   a = int(mean[1])
   b = int(mean[2])
   print L,a,b

我使用的是opencv 3和python 2.7

P.S。我已经尝试过背景减法器MOG2,据说它可以识别阴影但是它对于我的使用来说是嘈杂的并且不可行。

1 个答案:

答案 0 :(得分:0)

您可以定义一个遮罩来侵蚀图像,这样就可以打破山谷中的顶部和底部斑点。您可以将其应用于您的代码,如下所示:

# loop over the contours
for i, cnt in enumerate(contours):

   # compute the bounding box for the contour
   (x, y, w, h) = cv2.boundingRect(cnt)

   # reject contours outside size range
   if w > 250 or w < 30 or h > 250 or h < 30 :
          continue

   # make sure the box is inside the frame
   if x <= 0 or y <= 0 or x+w >= (WIDTH -1) or y+h >= (HIGHT -1):
          continue

   # ---------------
   # create a mask for erosion, you can play with the mask size/shape
   mask = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
   # erode the original image
   eroded_img = cv2.erode(binary,mask,iterations = 1)
   cv2.imshow("Eroded image",eroded_img)
   # find the middle of the two new contours
   _,new_contours,_ = cv2.findContours(eroded_img, cv2.RETR_EXTERNAL,
                      cv2.CHAIN_APPROX_SIMPLE)
   (_, y_t, _, h_t) = cv2.boundingRect(new_contours[0])
   (_, y_b, _, h_b) = cv2.boundingRect(new_contours[1])
   bottom_top_y = max(y_t, y_b) # highest y of bottom part
   top_bottom_y = min(y_t+h_t, y_b+h_b) # lowest y of top part
   half = top_bottom_y + (bottom_top_y - top_bottom_y)/2
   # ------------

   # isolate feature
   roi = lab[y:y+half, x:x+w]
   mask = binary[y:y+half, x:x+w]

   # calculate the mean of the colour
   mean = cv2.mean(roi, mask = mask)
   # note: mean is L a b
   L = int(mean[0])
   a = int(mean[1])
   b = int(mean[2])
   print L,a,b

希望它有所帮助!有关二进制图像上的形态学操作的更多示例,您可以检查here