20

Tôi đang cố tìm các đường ngang và dọc từ một hình ảnh xuất phát từ "tài liệu". Các tài liệu được quét các trang từ các hợp đồng và vì vậy các dòng trông giống như những gì bạn sẽ thấy trong một bảng hoặc trong một khối hợp đồng.Phát hiện đường ngang với OpenCV

Tôi đã thử OpenCV cho công việc. Việc thực hiện chuyển đổi Hough trong OpenCV có vẻ hữu ích cho công việc, nhưng tôi không thể tìm thấy bất kỳ sự kết hợp các tham số nào cho phép nó tìm kiếm một cách rõ ràng các đường thẳng đứng và nằm ngang. Tôi đã thử và không phát hiện cạnh. Không may mắn. Nếu bất cứ ai đã làm bất cứ điều gì tương tự, tôi quan tâm đến việc biết làm thế nào.

Xem tại đây hình ảnh của tôi trước và sau khi thử nghiệm với HoughP trong OpenCV. Đó là điều tốt nhất tôi có thể làm, http://dl.dropbox.com/u/3787481/Untitled%201.png

Vì vậy, bây giờ tôi tự hỏi liệu có một loại biến đổi nào khác có thể sử dụng hay không.

Tôi biết vấn đề này có thể giải quyết được vì tôi có các công cụ Nuance và ABBYY OCR có thể trích xuất một cách đáng tin cậy các đường ngang và dọc và trả lại cho tôi hộp giới hạn của các dòng.

Cảm ơn! Patrick.

Trả lời

25

Bạn đã xem mẫu mã từ tài liệu chức năng HoughLinesP chưa?

Tôi nghĩ bạn có thể sử dụng nó làm điểm bắt đầu cho thuật toán của mình. Để chọn ngang một đường thẳng đứng, bạn chỉ cần lọc ra các dòng khác theo góc đường thẳng.

UPDATE:

Như tôi thấy bạn cần phải tìm không phải là dòng nhưng ngang một cạnh thẳng đứng trên trang. Đối với nhiệm vụ này, bạn cần kết hợp một số bước xử lý để có kết quả tốt.

Đối với hình ảnh của bạn, tôi có thể nhận được kết quả tốt bằng cách kết hợp phát hiện cạnh Canny với HoughLinesP. Đây là mã của tôi (Tôi đã sử dụng python, nhưng tôi nghĩ rằng bạn thấy ý tưởng):

img = cv2.imread("C:/temp/1.png") 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
edges = cv2.Canny(gray, 80, 120) 
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1); 
for line in lines[0]: 
    pt1 = (line[0],line[1]) 
    pt2 = (line[2],line[3]) 
    cv2.line(img, pt1, pt2, (0,0,255), 3) 
cv2.imwrite("C:/temp/2.png", img) 

quả trông giống như:

+0

Hi Andrey, cảm ơn. Có, tôi đã thử HoughLinesP với nhiều biến khác nhau. Tôi đã điều chỉnh câu hỏi ban đầu của mình và bao gồm một liên kết đến hình ảnh tốt nhất mà tôi có thể thoát khỏi HoughLinesP. Và có, tôi đã cố gắng hạn chế chỉ các đường gần ngang. –

+0

Tuyệt vời. Rõ ràng là tôi đã bị mất máy dò Canny. Đó là một kết quả tốt. Tôi cũng đã tìm thấy một thuật toán gọi là Orthogonal Zig-Zag mà có thể lấy các dòng cung cấp và sau đó mở rộng chúng để xác định chiều rộng của dòng là tốt (đó là một cái gì đó mà HoughP không thể làm). –

+0

không có dấu chấm phẩy trong trăn;) – mak

5

Bạn có thể xem xét lại việc phát hiện dòng Hough vì đây phương thức tìm kiếm các dòng "toàn cầu", không nhất thiết phải là các đoạn thẳng. Gần đây, tôi đã triển khai một ứng dụng đã xác định "hình bình hành" - về cơ bản các ô vuông có thể được xoay và phối cảnh được rút ngắn do góc nhìn. Bạn có thể xem xét một cái gì đó tương tự.đường ống của tôi là:

  1. Chuyển đổi từ RGB sang dạng grayscale (cvCvtColor)
  2. mượt (cvSmooth)
  3. Threshold (cvThreshold)
  4. Phát hiện cạnh (cvCanny)
  5. Tìm đường nét (cvFindContours)
  6. Đường nét gần đúng với các đối tượng địa lý dạng đường (cvApproxPoly)

Trong ứng dụng, danh sách đường viền kết quả sẽ có khả năng lớn (tùy thuộc vào "tính xâm lược" của làm mịn và tăng cường tính năng của máy dò cạnh Canny. Bạn có thể cắt tỉa danh sách này bằng nhiều thông số khác nhau: số điểm được trả về từ công cụ tìm đường bao, vùng đường bao (cvContourArea), v.v. Từ kinh nghiệm của tôi, tôi mong rằng các dòng "hợp lệ" trong ứng dụng của bạn sẽ được xác định rõ thuộc tính đếm vùng và đỉnh. Ngoài ra, bạn có thể lọc đường viền dựa trên khoảng cách giữa điểm kết thúc, góc được xác định bởi đường kết nối điểm cuối, v.v.

Tùy thuộc vào lượng thời gian CPU của bạn, bạn luôn có thể ghép thuật toán Hough với một thuật toán như trên để xác định mạnh mẽ các đường ngang và dọc.

8

Nếu bạn chỉ muốn "dòng" chứ không phải "đoạn đường", tôi sẽ tránh sử dụng Canny, Hough, FindContours hoặc bất kỳ chức năng nào khác trong trường hợp bạn muốn tăng tốc độ trong mã của mình. Nếu hình ảnh của bạn không được xoay và những gì bạn muốn tìm luôn là dọc hoặc ngang, tôi sẽ chỉ sử dụng cv :: Sobel (một cho chiều dọc và một cho ngang) và tạo mảng tích lũy cho các cột và hàng. Sau đó, bạn có thể tìm kiếm tối đa trong các tích lũy hoặc hồ sơ như vậy, ví dụ bằng cách thiết lập một ngưỡng, và bạn sẽ biết hàng hoặc cột trong đó có một đường thẳng đứng hoặc nằm ngang.

+1

Bạn có biết các tham số được đặt cho các đường ngang và dọc trong cv :: sobel không? –

4

Không chuyển đổi RGB thành thang độ xám. Đôi khi, các màu khác nhau trong RGB có thể được hợp nhất thành cùng một giá trị thang độ xám, do đó, nó có thể bỏ lỡ một số đường nét. Bạn nên phân tích riêng từng kênh RGB.