2011-06-12 81 views
15

Tôi đang viết ứng dụng nhỏ để phát hiện hình dạng. Điều tôi cần làm ngay từ đầu là tìm hình dạng quan trọng nhất trên hình ảnh. Tôi bắt đầu từ một số tiền xử lý bao gồm chuyển đổi hình ảnh sang màu xám, đập và phát hiện cạnh. Hình ảnh trước và sau khi các hoạt động này được trình bày dưới đâyphát hiện hình dạng - xấp xỉ đường viền với OpenCV

Trước

enter image description here

Sau

enter image description here

Vì vậy, Bạn có thể thấy hình dạng chính là nhìn thấy được (tuy nhiên nó là một chút rải rác) và cũng có một số tiếng ồn (cây nhỏ vv). Những gì tôi cần làm là để trích xuất bằng cách nào đó chỉ là hình dạng quan trọng nhất (một trong những lớn nhất) - trong trường hợp này nó là một tháp. Những gì tôi muốn làm là sử dụng chức năng tìm đường viền trong opencv và sau đó bằng cách nào đó được tìm thấy một cách tương đối có liên quan với đa giác. Sau đó, tôi sẽ (bằng cách nào đó) tính toán diện tích countours và chọn chỉ số lớn nhất. Cho đến nay tôi manged (chỉ) để tìm đường nét sử dụng

cvFindContours(crated,g_storage,&contours); 

Tôi biết rằng có một chức năng

cvApproxPoly 

, tuy nhiên tôi không thể nhận được bất kỳ thông tin hữu ích cho các kết quả của chức năng này . Ai đó có thể cho tôi biết nếu có thể tính diện tích đường bao hoặc để ước tính mức độ cạnh tranh với đa giác. Có lẽ bạn có một ý tưởng tốt hơn làm thế nào để trích xuất chỉ có hình dạng quan trọng nhất?

Trả lời

5

Vấn đề chính của bạn là đường viền tháp nằm rải rác. Thật khó để tái tạo toàn bộ đường viền từ những mảnh nhỏ đó. Tối ưu hóa giai đoạn phát hiện cạnh bạn (thử cvAdaptiveThreshold), hoặc sử dụng cách tiếp cận khác nhau (có thể một cái gì đó giống như object segmentation)

Sau khi bạn có đường viền của bạn trong một mảnh, bạn có thể kiểm tra khu vực của nó như thế này:

CvSeq* convex_hull=cvConvexHull2(contour, storage, CV_CLOCKWISE, 2); 
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0); 
float size=fabs(cvContourArea(quad,CV_WHOLE_SEQ,0)); 

Bạn sẽ cần phải điều chỉnh các thông số. Nó được sử dụng để phát hiện hình chữ nhật.

8

Bạn không cần phải phát hiện cạnh ở đây. Chỉ cần ngưỡng tới một hình ảnh nhị phân và sau đó tìm các đốm màu (cvFindContours) trên đó. Bạn có thể sử dụng cvContourArea trên mỗi CvSeq đã trả về để tìm vùng của nó.

2

Bạn có thể sử dụng các hoạt động hình thái để ngăn chặn "tiếng ồn xung quanh" (giãn nở trong trường hợp của bạn). Nhưng bạn phải nhớ rằng khả năng sử dụng của các hoạt động hình thái phụ thuộc vào nhiệm vụ hiện tại. Ví dụ, nếu bạn có hai đối tượng đặt gần nhau, sự giãn nở có thể làm một đối tượng từ chúng.

6

Nếu bạn luôn luôn có một nền tảng kiểm soát, tôi sẽ đi cho các bước sau (như đề xuất cũng bởi @damian):

  1. binarization, tức là tạo ra một hình ảnh như nền = 0 và các vùng đối tượng = 1 (hoặc 255). Sau đó, bạn sẽ có một số vùng màu trắng trên hình ảnh của bạn. Có một số phương pháp để làm điều này, nhưng nếu nền của bạn được kiểm soát, bạn có thể sử dụng một ngưỡng cố định. Lưu ý rằng ở đây bạn đã loại bỏ nhiễu trong các đối tượng.Trong hình ảnh nhị phân, bạn luôn có thể sử dụng hình mở/đóng hình thái để làm mịn các đối tượng
  2. Sử dụng cvFindContours để tìm tất cả các đối tượng: bây giờ sẽ dễ dàng hơn.
  3. Điền các đường nét nhỏ hơn với màu nền bằng cách sử dụng cvFloodFill.
+0

Là một yêu cầu đối với quy trình Binarization. Nó luôn luôn khó để tìm thấy một giá trị ngưỡng tốt. Tôi luôn tính toán Hisogram và tìm kiếm một "Low Point". Ở đó bạn thường có giá trị Ngưỡng nive. Nếu bạn đang sử dụng JPEG, phương pháp này có thể không hoạt động tốt. –

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