5.27. Tìm kiếm hình tròn và hình chữ nhật

Các đường thẳng và đoạn thẳng bao phủ các cạnh thẳng trong khung hình được chụp, nhưng nhiều đặc trưng trong thực tế mà camera tìm kiếm không phải là thẳng. Một đồng xu nằm trên bàn là một hình tròn. Một nhãn in, một tờ giấy ghi chú, mặt trên của một hộp nhìn từ góc xiên là một tứ giác. Mô-đun image cung cấp một bộ phát hiện chuyên dụng cho từng loại: tìm kiếm theo phong cách Hough cho hình tròn và tìm kiếm dẫn xuất từ AprilTag cho các hình bốn cạnh.

Cả hai phương pháp đều tuân theo cùng một mẫu mà các bộ phát hiện đường thẳng sử dụng -- threshold kiểm soát số lượng phiếu bầu mà một phát hiện cần, roi thu hẹp phạm vi tìm kiếm, và các đối tượng được trả về đều mang cả vị trí lẫn độ lớn tin cậy -- nhưng không gian tham số và các giá trị mặc định hợp lý khác nhau đủ nhiều để cần được trình bày riêng.

5.27.1. Hough hình tròn

find_circles() chạy biến thể hình tròn của biến đổi Hough. Mỗi điểm ảnh cạnh từ bước tiền xử lý Sobel bỏ phiếu cho mọi hình tròn có thể đi qua nó; những hình tròn thu đủ phiếu bầu sẽ được trả về.

circles = img.find_circles(threshold=3500,
                            x_margin=10, y_margin=10, r_margin=10,
                            r_min=10, r_max=80, r_step=2)

for c in circles:
    img.draw_circle((c.x, c.y, c.r), color=(255, 0, 0))

threshold là tổng tối thiểu của độ lớn cạnh Sobel dọc theo hình tròn ứng viên. Các hình tròn lớn hơn dọc theo nhiều điểm ảnh hơn và do đó cần ngưỡng cao hơn để qua; một giá trị tìm thấy đồng xu có bán kính 20 điểm ảnh cũng sẽ kích hoạt trên nhiễu xung quanh cạnh 100 điểm ảnh, trong khi một giá trị được tinh chỉnh cho đồng xu lớn sẽ bỏ sót đồng xu nhỏ. Khi phạm vi bán kính mục tiêu đã biết, ngưỡng phù hợp tỷ lệ với chu vi -- khoảng threshold = 50 * 2 * pi * r cho một điểm khởi đầu hợp lý và giá trị đúng có được sau một vòng tinh chỉnh ngắn.

r_min, r_max, và r_step thiết lập phạm vi tìm kiếm bán kính. Nếu không có giới hạn, bộ phát hiện sẽ tìm kiếm mọi bán kính từ vài điểm ảnh đến nửa chiều rộng ảnh, vừa chậm vừa dễ tạo ra dương tính giả. Đặt r_minr_max để bao quanh kích thước mục tiêu dự kiến với biên đủ rộng (ví dụ: r_min=15, r_max=25 cho đồng xu biết là khoảng 20 điểm ảnh) giảm đáng kể khối lượng công việc và cải thiện tỷ lệ tín hiệu-trên-nhiễu của phiếu bầu. r_step kiểm soát độ chi tiết của tìm kiếm; bước lớn hơn chạy nhanh hơn và có thể bỏ sót hình tròn có bán kính thực nằm giữa hai giá trị được lấy mẫu. Giá trị mặc định r_step=2 là sự cân bằng hợp lý.

x_margin, y_margin, và r_margin kiểm soát việc gộp các phát hiện gần nhau, giống như cách theta_marginrho_margin làm với phát hiện đường thẳng. Một hình tròn vật lý duy nhất trong ảnh bỏ phiếu cho một cụm hình tròn ứng viên có tâm và bán kính đồng ý với nhau trong vài điểm ảnh; các biên gộp mỗi cụm thành đỉnh của nó trước khi danh sách kết quả được xây dựng. Biên lớn hơn trả về ít phát hiện hơn nhưng đáng tin cậy hơn; biên nhỏ hơn trả về nhiều phát hiện hơn với các trùng lặp có thể xảy ra.

x_stridey_stride bước qua quá trình quét bỏ phiếu, giống như cách chúng làm trong các bộ phát hiện khác. Giá trị mặc định 21 phù hợp với hầu hết các ảnh; tăng cả hai lên 4 là đánh đổi tốc độ tiêu chuẩn cho ảnh được biết là chứa các hình tròn lớn.

Mỗi Circle được trả về mang x, y, r (tâm và bán kính) và magnitude (tổng phiếu bầu, hữu ích như điểm tin cậy để sắp xếp hoặc lọc). Vẽ lại phát hiện vào khung hình chỉ cần một lệnh -- draw_circle() nhận 3-tuple (x, y, r), có thể truy cập trực tiếp là (c.x, c.y, c.r) từ kết quả.

5.27.2. Hình chữ nhật

find_rects() mượn bộ phát hiện tứ giác từ quy trình xử lý AprilTag -- cùng một quy trình định vị hình vuông đen xung quanh một thẻ được hiển thị độc lập như một bộ tìm kiếm hình chữ nhật đa năng.

rects = img.find_rects(threshold=12000)

for r in rects:
    img.draw_rectangle(r.rect, color=(0, 255, 0))
    for corner in r.corners:
        img.draw_circle((corner[0], corner[1], 4),
                        color=(0, 255, 0))

threshold là tổng tối thiểu của độ lớn cạnh xung quanh chu vi của hình chữ nhật. Một hình chữ nhật đen trên nền trắng được in trong khung hình đủ sáng dễ dàng vượt qua 10000; một hình chữ nhật mờ trên nền có kết cấu có thể cần giảm xuống 2000 -- đánh đổi dương tính giả lấy độ nhạy. Giống như bộ phát hiện hình tròn, giá trị đúng có được sau một vòng tinh chỉnh nhanh với các mục tiêu dự định trong tầm nhìn.

Bộ phát hiện có tính chiếu xạ -- nó tìm các tứ giác có các cạnh thẳng nhưng không nhất thiết phải song song hoặc căn chỉnh theo trục. Một nhãn nhìn từ góc xiên trông giống hình thang trong ảnh, và bộ phát hiện hình chữ nhật tìm thấy nó đúng; một hình chữ nhật căn chỉnh theo trục chỉ là trường hợp suy biến khi bốn góc tình cờ tạo thành hộp vuông góc. roi giới hạn phạm vi tìm kiếm; các đối số từ khóa còn lại lấy giá trị mặc định từ quy trình xử lý AprilTag và hiếm khi cần tinh chỉnh.

Mỗi Rect được trả về mang hộp giới hạn căn chỉnh theo trục -- x, y, w, h, cộng với 4-tuple rectdraw_rectangle() yêu cầu -- bốn góc được phát hiện dưới dạng corners. Hộp giới hạn là thứ ứng dụng dùng để xác định vị trí và kích thước thô; các góc mô tả tứ giác chiếu xạ. Khi camera đang xem một mục tiêu phẳng từ một góc và ứng dụng cần hoàn tác phần biến dạng hình thang -- đọc văn bản trên nhãn, lấy mẫu màu từ miếng phẳng -- các góc đưa thẳng vào rotation_corr() với từ khóa corners= (xem hiệu chỉnh ống kính và phối cảnh), và đầu ra là hình chữ nhật đã được chỉnh thẳng sẵn sàng cho bất kỳ phân tích nào tiếp theo.

Cảnh báo

Vì bộ phát hiện được tinh chỉnh cho những gì quy trình xử lý AprilTag cần -- tứ giác với đường viền mạnh, độ tương phản cao, như một đường viền thẻ đen trên giấy trắng -- nó không phải là một lượt tìm-mọi-hình-chữ-nhật. Các hình chữ nhật với độ tương phản mềm, cạnh có kết cấu, hoặc môi trường xung quanh bận rộn có thể hoàn toàn không được phát hiện. Hiệu quả hoạt động phụ thuộc vào tình huống: hãy kiểm tra với các mục tiêu thực tế sớm, trước khi xây dựng quy trình xử lý xung quanh nó.

5.27.3. Khi bộ phát hiện hoạt động sai

Các hình tròn đặc biệt được hưởng lợi từ một bộ lọc trước trên đầu vào. Một khung hình nhiễu tạo ra nhiều điểm ảnh cạnh lạc đang bỏ phiếu, và không gian Hough kết quả có các đỉnh mờ rộng mà bộ gộp khó có thể tách biệt. Một lượt gaussian() hoặc mean() trước find_circles() làm mịn nhiễu và giữ lại các cạnh thật; bộ phát hiện trả về các đỉnh sạch hơn trong thời gian ngắn hơn.

Đối với hình chữ nhật, chế độ lỗi phổ biến là ngược lại: độ tương phản thấp giữa hình chữ nhật và nền của nó có nghĩa là tổng độ lớn cạnh không bao giờ vượt qua threshold. Một lượt histeq() để phân phối lại phạm vi độ sáng trên toàn bộ dải 0-đến-255 khôi phục độ tương phản mà bộ phát hiện cần. (Độ tương phản phải tồn tại ở đâu đó trong ảnh; cân bằng biểu đồ tần suất chỉ có thể khuếch đại những gì đã có sẵn.)