2015-09-05 15 views
5

Tôi đang sử dụng phép trừ nền để phân tích các đối tượng chuyển động của cảnh ngoài trời. Khi mặt trời lặn, tôi có vấn đề với bóng tối. Tôi đang sử dụng đường nét để cô lập các đối tượng. Tại thời điểm này tôi chỉ đơn giản là phân tích nửa trên của đường bao như bóng thường ở nửa dưới.Vị trí kích thước tối thiểu đường viền OpenCV trong python

Hãy tưởng tượng một đường viền của một con vịt cao su, những gì tôi muốn làm là tìm vị trí y của cổ vịt, đó là nơi đường viền ở kích thước ngang tối thiểu của nó. Ai đó có thể vui lòng chỉ cho tôi đi đúng hướng để tìm "cổ vịt" không?

enter image description here

Trong mã, binary là một hình ảnh ngưỡng cửa của các đối tượng di chuyển, HIGHTWIDTH là chiều cao và chiều rộng của hình ảnh, lab là cùng một hình ảnh trong không gian LAB màu.

Tôi muốn thay thế đường half = int(h/2) bằng chức năng tìm vị trí y của đường ngang để cắt "cổ vịt".

_,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 

Tôi đang sử dụng opencv 3 và python 2.7

T.B. Tôi đã thử nền trừ MOG2 được cho là để xác định bóng nhưng nó là cách để ồn ào cho việc sử dụng của tôi và không khả thi.

+3

Thêm vào câu hỏi của bạn một vài hình ảnh với kết quả thực tế và dự kiến. Nhấp vào liên kết chỉnh sửa bên dưới các thẻ. Bạn không có đủ danh tiếng để thêm hình ảnh, nhưng bạn có thể đăng liên kết công khai từ imgur hoặc tương tự – Miki

+0

Xin chào Miki, tôi đã thêm một bản phác thảo sẽ giúp làm rõ, vui lòng hỏi bất kỳ điều gì khác. Tôi đã nghĩ về 3 giải pháp có thể, 1) Bằng cách nào đó sử dụng khoảnh khắc, 2) Lặp lại qua danh sách đường bao để tìm các điểm rẽ, 3) Tổng các hàng theo chiều ngang để lấy hồ sơ và sau đó tìm các điểm quay của cấu hình. Hai người đầu tiên tôi không có ý tưởng về một số trợ giúp về cách sử dụng các khoảnh khắc hoặc cách truy cập và diễn giải danh sách đường bao sẽ giúp ích rất nhiều. Hoặc bất kỳ đề xuất nào khác sẽ được đánh giá rất nhiều. – Johno

+0

Xin lỗi khi bạn đang cố gắng làm như đã hỏi nhưng hãy tránh Dropbox/các liên kết tạm thời khác nếu chúng tôi có thể - chúng tôi muốn những câu hỏi này giúp mọi người trong nhiều năm và nếu bạn xóa tệp dropbox của mình trong tương lai, câu hỏi này ít có giá trị hơn. SO Có một sự sắp xếp với imgur để đảm bảo tất cả các hình ảnh sẽ được xung quanh trong suốt thời gian. Tôi đã thực hiện nó cho bạn trong trường hợp này. Hy vọng bạn tìm thấy câu trả lời của bạn! – Basic

Trả lời

0

Bạn có thể xác định mặt nạ để xóa hình ảnh để bạn có thể chia các đốm màu trên cùng và dưới cùng khỏi thung lũng. Bạn có thể áp dụng điều đó cho mã của mình như sau:

# 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 

Hy vọng điều đó sẽ hữu ích! Để biết thêm ví dụ về hoạt động hình thái trên hình ảnh nhị phân, bạn có thể kiểm tra here.

+0

Ike, cảm ơn rất nhiều về đầu vào của bạn. Điều này chắc chắn là một cách để làm điều đó.Tôi đã sử dụng erode để giảm kích thước mặt nạ để các cạnh rất của đối tượng không được bao gồm trong tính toán công nhận của tôi. Có lẽ tôi sẽ xói mòn trong một vòng lặp cho đến khi có 2 đường nét và sau đó phát triển các đường viền hàng đầu trở lại gần kích thước ban đầu. Chúc mừng :-) – Johno

Các vấn đề liên quan