Contours (đường viền) và Find contours (tìm contours)

Một phần của tài liệu nghiên cứu thư viện opencv ứng dụng trong việc nhận dạng biển báo giao thông (Trang 43 - 46)

CHƯƠNG 2: CƠ SỞ LÝ THUYẾT

2.4. Lý thuyết xử lý ảnh và các hàm hỗ trợ bởi OpenCV

2.4.3. Contours (đường viền) và Find contours (tìm contours)

Constours (đường viền) là tập hợp các điểm được nối với nhau, và hầu như vị trí của tập hợp điểm này là đường nét bao quanh của đối tượng trong hình.

Sự khác nhau giữa edges và contours là edges là những điểm có giá trị intensiy gradient lớn so với các điểm lân cận và các giá trị intensity gradient này không bao quanh đối tượng và chúng rất nhiễu.

findContours

Tìm contours trong hình ảnh binary và trích xuất ra hệ thống cấp bậc contours tree (cây contours) của tập hợp edges được kết nối với nhau được minh hoạ như sau:

Một hình ảnh có các vùng màu trắng A, B, C,... được dùng để tìm contours

Kết quả của contours được thể hiện ở 2 dạng:

• exterior boundaries (đường biên bên ngoài) của vùng màu trắng được minh hoạ bởi các đường đứt nét hay còn được gọi là contour (cN – N là số)

• interior boundaries (đường biên bên trong) được minh hoạ bởi các đường chấm hay còn gọi là hole (ký hiệu hN – N là số)

Hình 2.9: Hình ảnh dùng để tìm contours, có các vùng A, B, C,... màu trắng trên nền đen

A

B C

D E

Hình 2.10: Kết của của việc tìm contours, được thể hiện ở 2 dạng: exterior (đường đứt nét) và hole (đường chấm)

c0

h00 h01

h0000 c000 c010

h0100

c01000 c01001

Contours tree của hình ảnh ví dụ ở trên có contour c0 ở gốc, có 2 con là hole h00 và h01, tương tự contour c000 có 1 con là h0000, và tương tự cho các contour còn lại.

void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset = Point())

void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())

Trong đó,

• image – Hình ảnh nguồn đơn kênh 8-bit, trong quá trình tìm contours hàm sẽ chỉnh sửa, thay đổi image

• contours – Kết quả của tìm contours, mỗi contours được lưu trữ trong một vector điểm (thư viện chuẩn của C++), nên kiểu dữ liệu truyền là vector<vector<Point>>

• hierarchy – vector lưu trữ thông tin kết nối của các contour trong hệ thống contours tree nên kiểu dữ liệu truyền là vector<Vec4i>. Mỗi contour thứ i (contours[i]) có:

◦ hierarchy[i][0] – chỉ số của contour kế tiếp (h_next)

◦ hierarchy[i][1] – chỉ số của contour trước đó (h_prev)

◦ hierarchy[i][2] – chỉ số của contour con đầu tiên (v_next)

◦ hierarchy[i][3] – chỉ số của contour cha (v_prev)

Mọi chỉ số đều bắt đầu từ 0 (0-based indices). Nếu contours[i] không có phần tử tương ứng nào thì giá trị tại đó là một số âm.

• mode – Cách lưu trữ hay thể hiện của contour tree

CV_RETR_EXTERNAL: chỉ tìm chính xác các exterior contours

CV_RETR_LIST: tìm tất cả các contours và ko thiết lập hệ thống phân cấp, chỉ lưu trữ dạng danh sách

CV_RETR_CCOMP: tìm tất cả các contours và tổ chức thành hệ thống 2 cấp bậc, trong đó cấp 1 là danh sách các exterior contours, cấp 2 là danh sách các interior contours

CV_RETR_TREE: tìm tất cả các contours và tổ chức thành hệ thống cây phân cấp

• method – Cách hay phương pháp tìm contours

CV_CHAIN_CODE: Sử dụng giải thuật Freeman chain code

CV_CHAIN_APPROX_NONE: Sử dụng giải thuật Freemain chain code, nhưng dịch tất cả các điểm của chain code thành điểm bình thường

CV_CHAIN_APPROX_SIMPLE:

CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS: sử dụng giải thuật TehChin chain

• offset – Điểm tuỳ chọn mà ở đó các contour point sẽ dịch duyển. Chỉ sử dụng đối số này khi tìm contours trên image RoI (Region of Interest – một vùng ảnh quan tâm) và phân tích kết quả cho toàn bộ hình ảnh.

Contours là một công cụ hữu ích cho việc phân tích hình dạng hình học, phát hiện và nhận dạng đối tượng.

contourArea

Tính diện tích của contour.

double contourArea(InputArray contour, bool oriented = false)

Trong đó,

• contour – Vector điểm của contour, truyền vào std::vector<Point>

• oriented – Flag chỉ hướng của contour. Nếu truyền vào giá trị true, kết quả diện tích của contour sẽ có dấu (âm hoặc dương) tuỳ thuộc vào hướng của contour là cùng chiều hay ngược chiều với kim đồng hồ (clockwise or counter-clockwise)

boundingRect

Tính toán một hình chữ nhật thẳng đứng có diện tích nhỏ nhất bao quanh một tập hợp điểm.

Rect boundingRect(InputArray points)

Trong đó,

• points – tập hợp điểm được lưu trữ trong std::vector<Point>

Ví dụ 2.12: Tiếp theo ví dụ trên, cài đặt phát hiện đối tượng có diện tích contours >= 3500 và sau đó vẽ hình chữ nhật bao quanh đối tượng.

#include "opencv2/opencv.hpp"

using namespace std;

using namespace cv;

#define WINDOW_NAME "Detect object"

Hình 2.11: Minh hoạ cách lưu trữ / thể hiện của hệ thống contours tree

CV_RETR_EXTERNAL CV_RETR_TREE

first = c0 CV_RETR_LIST

first = c01000 - c01001 - h0100 - c010 - c000 - h01 - h00 - c0 CV_RETR_CCOMP

first = c01000 - c01001 - c010 - c000 - c0

h0100 h0000 h01 - h00| | |

first = c0

h00 - h01 c000 c010 h0000 h0100

c01000 - c010001

|

| |

| |

|

Mat brgImage, hsvImage;

vector<vector<Point>> contours;

int main(int argc, char const* argv[]) { brgImage = imread(argv[1], IMREAD_COLOR);

cvtColor(brgImage, hsvImage, COLOR_BGR2HSV);

// Only use Hue and Satuaration value Mat hsImage(brgImage.size(), CV_8UC2);

int fromTo[] = { 0, 0, 1, 1 };

mixChannels(&hsvImage, 1, &hsImage, 1, fromTo, 2);

// Threshold range of blue color in HS space Mat edgesImage(brgImage.size(), CV_8UC1);

inRange(hsImage, Scalar(110, 100), Scalar(130, 255), edgesImage);

// Canny edges detection

medianBlur(edgesImage, edgesImage, 3);

Canny(edgesImage, edgesImage, 40, 40 * 3, 3);

// Find and extract contours

findContours(edgesImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

// Only select object has area >= 3500

for (size_t i = 0; i < contours.size(); i++) {

Rect regionOfInterest = boundingRect(contours[i]);

if (contourArea(contours[i]) <= 3500) { contours.erase(contours.begin() + i);

i--;

} }

// Draw objec with a rectangle

for (size_t i = 0; i < contours.size(); i++) {

Rect regionOfInterest = boundingRect(contours[i]);

rectangle(brgImage, regionOfInterest, Scalar(0, 0, 255));

}

imshow(WINDOW_NAME, brgImage);

waitKey(0);

return 0;

}

Một phần của tài liệu nghiên cứu thư viện opencv ứng dụng trong việc nhận dạng biển báo giao thông (Trang 43 - 46)

Tải bản đầy đủ (PDF)

(65 trang)