Thinning algorithm in OpenCV – Thuật toán mỏng hóa trong OpenCV.
Đây là bài dịch từ tiếng Anh mô tả thuật toán biến đổi hình ảnh làm cho mỏng hơn. Các bạn có thể tham khảo morphology – hình thái học.
Đây là hàm thực hiện việc mỏng hóa ảnh nhị phân dùng thuật toán Zhang-Suen. Thuật toán này được định nghĩa: “Thuật toán xử lý song song cho việc mỏng hóa mẫu kỹ thuật số”, tác giả là T.Y. Zhang và C.Y. Suen.
Tôi có viết hàm này vì không có hàm tương tự trong OpenCV phiên bản 2.4.3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
1. While points are deleted do 2. For all pixels p(i,j) do 3. if (a) 2 ≤ B(P1) ≤ 6 (b) A(P1) = 1 (c) Apply one of the following: 1. P2 x P4 x P6 = 0 in odd iterations 2. P2 x P4 x P8 = 0 in even iterations (d) Apply one of the following: 1. P4 x P6 x P8 = 0 in odd iterations 2. P2 x P6 x P8 = 0 in even iterations then 4. Delete pixel p(i,j) 5. end if 6. end for 7. end while |
Với điều kiện A(P1) là 0 hoặc 1 theo chiều kim đồng hồ từ P9, và B(P1) là số lượng giá trị khác 0 lân cận P1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/** * Code for thinning a binary image using Zhang-Suen algorithm. */ #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> /** * Perform one thinning iteration. * Normally you wouldn't call this function directly from your code. * * @param im Binary image with range = 0-1 * @param iter 0=even, 1=odd */ void thinningIteration(cv::Mat& im, int iter) { cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1); for (int i = 1; i < im.rows-1; i++) { for (int j = 1; j < im.cols-1; j++) { uchar p2 = im.at<uchar>(i-1, j); uchar p3 = im.at<uchar>(i-1, j+1); uchar p4 = im.at<uchar>(i, j+1); uchar p5 = im.at<uchar>(i+1, j+1); uchar p6 = im.at<uchar>(i+1, j); uchar p7 = im.at<uchar>(i+1, j-1); uchar p8 = im.at<uchar>(i, j-1); uchar p9 = im.at<uchar>(i-1, j-1); int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) + (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1); int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9; int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8); int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8); if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0) marker.at<uchar>(i,j) = 1; } } im &= ~marker; } /** * Function for thinning the given binary image * * @param im Binary image with range = 0-255 */ void thinning(cv::Mat& im) { im /= 255; cv::Mat prev = cv::Mat::zeros(im.size(), CV_8UC1); cv::Mat diff; do { thinningIteration(im, 0); thinningIteration(im, 1); cv::absdiff(im, prev, diff); im.copyTo(prev); } while (cv::countNonZero(diff) > 0); im *= 255; } /** * This is an example on how to call the thinning function above. */ int main() { cv::Mat src = cv::imread("test_image.png"); if (src.empty()) return -1; cv::Mat bw; cv::cvtColor(src, bw, CV_BGR2GRAY); cv::threshold(bw, bw, 10, 255, CV_THRESH_BINARY); thinning(bw); cv::imshow("src", src); cv::imshow("dst", bw); cv::waitKey(0); return 0; } |
Kết quả
Nguồn http://opencv-code.com/quick-tips/implementation-of-thinning-algorithm-in-opencv/
Cảm ơn thông tin hữu ích . Cần thêm blog của bạn vào bookmark
I have been surfing online greater than three hours today, yet I never found any attention-grabbing article like yours. It’s lovely price sufficient for me. In my view, if all website owners and bloggers made just right content as you did, the internet shall be much more helpful than ever before.