Xử lý ảnh thường người ta chỉ xử lý 1 phần của ảnh chứ ít khi xử lý toàn bộ. Nhận diện khuôn mặt thì chỉ lấy vùng chứa khuôn mặt, xử lý biển số người ta crop biển số. Và vùng cần lấy ra đó là ROI – region of interest.
C++ có con trỏ rất hay, nó quản lý bộ nhớ RAM hiệu quả, làm giảm việc cấp phát và thu hồi bộ nhớ. Do đó sử dụng con trỏ sẽ giúp chương trình xử lý nhanh hơn. Nếu bạn hiểu con trỏ thì xử lý một phần hình ảnh bằng ROI cũng tương tự mà thôi
Trong bài này sử dụng ảnh bên dưới để làm ví dụ
Thực hành
Trong opencv, ảnh là ma trận, và ROI cũng là ma trận được quản lý bởi con trỏ. Code dưới đây tạo ROI là hình vuông size 100 ở vị trí (0; 0)
1 2 3 |
cv::Mat mat = cv::imread("image.jpg"); cv::Rect roi = cv::Rect(0, 0, 100, 100); cv::Mat matRoi = mat(roi); |
Gán giá trị 0 cho ROI thì ảnh gốc như sau
1 2 |
matRoi = 0; cv::imshow("mat", mat); |
Ta thấy được vùng được chọn đã thành màu đen (giá trị 0)
Tương tự như vậy, gán 1 màu nào đó cho roi
1 2 |
matRoi = cv::Scalar(146,223,123); cv::imshow("mat", mat); |
Hoặc gán bằng 1 vùng ảnh khác, code bên dưới gán bằng hình vuông size 100 tại vị trí (200,200). Lưu ý không gán trực tiếp được mà phải xài hàm copyTo()
1 2 3 |
cv::Mat matRoi2 = mat(cv::Rect(200, 200, 100, 100)); matRoi2.copyTo(matRoi); cv::imshow("mat", mat); |
Kết luận
Dùng ROI cũng giống như crop ảnh, tuy nhiên khác ở chỗ dùng ROI quản lý bộ nhớ tốt hơn. Không phải tạo vùng nhớ mới chứa ảnh đã crop nên tốc độ xử lý sẽ nhanh hơn crop ảnh. Đồng thời cũng dễ xử lý với những yêu cầu như blend ảnh hoặc các tính toán phức tạp khác.