2016-04-30 17 views
6

Tôi đang làm phát hiện học sinh cho dự án trường học của tôi. Đây là lần đầu tiên tôi làm việc với OpenCV và Python, sử dụng phiên bản Python 3.4.2 và OpenCV 3.1.0.phát hiện học sinh trong OpenCV & Python

Tôi đang sử dụng máy ảnh Raspberry Pi NoIR và tôi đang nhận được hình ảnh tốt. .

Nhưng tôi không thể phát hiện một học sinh độc đáo (vì tia sáng lóe lên, lông mi và bóng tôi tham khảo một số mã trên web và sau đây là một phần của mã mà

... 

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) 

# capture frames from the camera 
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): 

    image = frame.array 
    cv2.imshow("image", image) 


    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 
    retval, thresholded = cv2.threshold(gray, 80, 255, 0) 
    cv2.imshow("threshold", thresholded) 

    closed = cv2.erode(cv2.dilate(thresholded, kernel, iterations=1), kernel, iterations=1) 
    #closed = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel) 

    cv2.imshow("closed", closed) 

    thresholded, contours, hierarchy = cv2.findContours(closed, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) 

    drawing = np.copy(image) 
    cv2.drawContours(drawing, contours, -1, (255, 0, 0), 2) 

    for contour in contours: 

     area = cv2.contourArea(contour) 
     bounding_box = cv2.boundingRect(contour) 

     extend = area/(bounding_box[2] * bounding_box[3]) 

     # reject the contours with big extend 
     if extend > 0.8: 
      continue 

     # calculate countour center and draw a dot there 
     m = cv2.moments(contour) 
     if m['m00'] != 0: 
      center = (int(m['m10']/m['m00']), int(m['m01']/m['m00'])) 
      cv2.circle(drawing, center, 3, (0, 255, 0), -1) 

     # fit an ellipse around the contour and draw it into the image 
     try: 
      ellipse = cv2.fitEllipse(contour) 
      cv2.ellipse(drawing, box=ellipse, color=(0, 255, 0)) 
     except: 
      pass 

    # show the frame 
    cv2.imshow("Drawing", drawing) 

    ... 

hình ảnh đầu vào.: hình ảnh

enter image description here

Output:

enter image description here

Làm cách nào để xóa các phần của hình ảnh không liên quan đến học sinh, như được hiển thị ở trên?

Ngoài câu trả lời, mọi gợi ý cũng được hoan nghênh.

+0

liên quan: [Đẩy nhanh giải thuật mắt theo dõi vectorized trong NumPy] (https://stackoverflow.com/questions/35996257/speeding-up-vectorized-eye-tracking-algorithm-in-numpy) . Bạn cũng có thể kiểm tra tính tròn ([mã ví dụ] (https://github.com/Itseez/opencv/blob/3.1.0/modules/features2d/src/blobdetector.cpp#L222)). – Catree

+0

Các tùy chọn khác: phát hiện trực tiếp vòng tròn với [HoughCircles] (http://docs.opencv.org/3.1.0/dd/d1a/group__imgproc__feature.html#ga47849c3be0d0406ad3ca45db65a25d2d) và/hoặc chỉ giữ đường bao nếu vùng bên trong tối hơn ở ngoài. Nếu mắt luôn ở giữa và ở cùng khoảng cách, bạn cũng có thể xác định một vùng quan tâm (ROI) + sử dụng vùng đó. – Catree

+0

Tôi sẽ sử dụng [erode] (http://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode) trên hình ảnh nhị phân và sau đó chỉ cần thực hiện [HoughCircles] (http: //docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html) để phát hiện vòng kết nối quan trọng nhất trong hình ảnh. – 0x90

Trả lời

4

Có một số điều bạn có thể làm. Làm thế nào họ làm việc tốt phụ thuộc vào bao nhiêu biến thể có trong những hình ảnh bạn muốn áp dụng các thuật toán trên. Bạn có thể đưa ra một vài giả định và sau đó loại bỏ tất cả các ứng cử viên không đáp ứng chúng.

remove nhận diện nhỏ

Lúc đầu, tôi sẽ xem xét loại bỏ các ứng cử viên quá nhỏ bằng cách thêm dòng này vào đầu vòng lặp của bạn:

if area < 100: 
    continue 

Ngưỡng được chọn một cách ngẫu nhiên và làm việc tốt cho này hình ảnh cụ thể. Nó loại bỏ gần như tất cả các phát hiện sai. Chỉ còn cái lớn nhất. Nhưng bạn phải kiểm tra nó với các hình ảnh khác của bạn và điều chỉnh nó theo nhu cầu của bạn.

enter image description here

loại bỏ nhận diện mà không phải là vòng

Một giả định bạn có thể làm là học sinh thường tròn và bạn có thể loại bỏ tất cả các phát hiện đó không phải là 'tròn' đủ. Một thước đo đơn giản về độ tròn là xem tỷ lệ chu vi đến khu vực.

circumference = cv2.arcLength(contour,True) 
circularity = circumference ** 2/(4*math.pi*area) 

Thông tư là khoảng 2,72 cho bóng ở bên phải và 1,31 cho học sinh.

cải thiện vòng tròn

Bạn nhận thấy rằng đường viền của học trò không hoàn toàn tròn do phản xạ. Bạn có thể cải thiện điều này bằng cách tính toán vỏ lồi của các đường bao.

contour = cv2.convexHull(contour) 

Nếu bạn làm điều đó trước khi tính diện tích và chu vi, bạn sẽ nhận được giá trị tròn 1,01 và 1,37. (Một vòng tròn hoàn hảo có một vòng tròn của 1) Điều này có nghĩa là khiếm khuyết từ sự phản ánh đã gần như hoàn toàn sửa chữa. Điều này có thể không cần thiết trong trường hợp này nhưng có thể hữu ích trong trường hợp có nhiều phản xạ hơn.

enter image description here

+0

cảm ơn! tôi thiết lập một giới hạn tròn 1.1, và làm việc độc đáo. Tôi muốn thực hiện dự án này 'thời gian thực'. vì hình thái học (theo quan điểm của tôi), FPS trở nên giảm khi kích thước hạt nhân trở nên lớn hơn. tôi có thể cải thiện hiệu suất hình thái không? –

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