Skip to content

Commit

Permalink
Update ximgproc.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
sturkmen72 committed Oct 2, 2024
1 parent 6965db1 commit 6246fad
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 68 deletions.
61 changes: 18 additions & 43 deletions modules/ximgproc/include/opencv2/ximgproc.hpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,6 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#ifndef __OPENCV_XIMGPROC_HPP__
#define __OPENCV_XIMGPROC_HPP__
Expand Down Expand Up @@ -68,6 +36,8 @@
/**
@defgroup ximgproc Extended Image Processing
@{
@defgroup ximgproc_binarization Binarization
@defgroup ximgproc_edge Structured forests for fast edge detection
This module contains implementations of modern structured edge detection algorithms,
Expand Down Expand Up @@ -124,7 +94,7 @@ namespace cv
namespace ximgproc
{

//! @addtogroup ximgproc
//! @addtogroup ximgproc_binarization
//! @{

enum ThinningTypes{
Expand Down Expand Up @@ -179,15 +149,20 @@ CV_EXPORTS_W void niBlackThreshold( InputArray _src, OutputArray _dst,
int blockSize, double k, int binarizationMethod = BINARIZATION_NIBLACK,
double r = 128 );

/** @brief Applies a binary blob thinning operation, to achieve a skeletization of the input image.
/** @brief Performs binary image thinning to obtain a skeletonized representation of the input image.
The function transforms a binary blob image into a skeletized form using the technique of Zhang-Suen.
This function applies a thinning algorithm, reducing the binary blobs in the input image to a skeletal form.
By default, it uses the Zhang-Suen technique, which iteratively removes pixels from the boundaries of the blobs
while preserving the overall structure and connectivity of the objects.
@param src Source image: an 8-bit, single-channel binary image where the blobs are represented by pixels with a value of 255 (white),
and the background is 0 (black).
@param dst Destination image of the same size and type as src, where the result of the thinning operation will be stored.
This operation can be performed in-place, meaning `src` and `dst` can be the same.
@param thinningType The thinning algorithm to apply. By default, the Zhang-Suen algorithm is used. See cv::ximgproc::ThinningTypes for other options.
*/
CV_EXPORTS_W void thinning(InputArray src, OutputArray dst, int thinningType = THINNING_ZHANGSUEN);

@param src Source 8-bit single-channel image, containing binary blobs, with blobs having 255 pixel values.
@param dst Destination image of the same size and the same type as src. The function can work in-place.
@param thinningType Value that defines which thinning algorithm should be used. See cv::ximgproc::ThinningTypes
*/
CV_EXPORTS_W void thinning( InputArray src, OutputArray dst, int thinningType = THINNING_ZHANGSUEN);

/** @brief Performs anisotropic diffusion on an image.
Expand Down
47 changes: 24 additions & 23 deletions modules/ximgproc/src/thinning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,34 +95,32 @@ static uint8_t lut_guo_iter1[] = {
static void thinningIteration(Mat &img, Mat &marker, const uint8_t* const lut) {
int rows = img.rows;
int cols = img.cols;
marker.col(0).setTo(1);
marker.col(cols - 1).setTo(1);
marker.row(0).setTo(1);
marker.row(rows - 1).setTo(1);

marker.forEach<uchar>([=](uchar& value, const int position[]) {
int i = position[0];
int j = position[1];
if (i == 0 || j == 0 || i == rows - 1 || j == cols - 1) { return; }
// Parallelized iteration over pixels excluding the boundary
parallel_for_(Range(1, rows - 1), [&](const Range& range) {
for (int i = range.start; i < range.end; i++) {
uchar* imgRow = img.ptr(i);
uchar* markerRow = marker.ptr(i);
for (int j = 1; j < cols - 1; j++) {
if (imgRow[j]) {
uchar p2 = imgRow[j - cols] != 0;
uchar p3 = imgRow[j - cols + 1] != 0;
uchar p4 = imgRow[j + 1] != 0;
uchar p5 = imgRow[j + cols + 1] != 0;
uchar p6 = imgRow[j + cols] != 0;
uchar p7 = imgRow[j + cols - 1] != 0;
uchar p8 = imgRow[j - 1] != 0;
uchar p9 = imgRow[j - cols - 1] != 0;

auto ptr = img.ptr(i, j); // p1
if (ptr[0]) {
uchar p2 = ptr[-cols] != 0;
uchar p3 = ptr[-cols + 1] != 0;
uchar p4 = ptr[1] != 0;
uchar p5 = ptr[cols + 1] != 0;
uchar p6 = ptr[cols] != 0;
uchar p7 = ptr[cols - 1] != 0;
uchar p8 = ptr[-1] != 0;
uchar p9 = ptr[-cols - 1] != 0;

int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7);
value = lut[neighbors];
int neighbors = p9 | (p2 << 1) | (p3 << 2) | (p4 << 3) | (p5 << 4) | (p6 << 5) | (p7 << 6) | (p8 << 7);
markerRow[j] = lut[neighbors];
}
}
}
});

// Bitwise AND and reset marker for the next iteration
img &= marker;
marker.setTo(0);
}

// Apply the thinning procedure to a given image
Expand All @@ -132,7 +130,10 @@ void thinning(InputArray input, OutputArray output, int thinningType){
// Enforce the range of the input image to be in between 0 - 255
processed /= 255;
Mat prev = processed.clone();
Mat marker = Mat::zeros(processed.size(), CV_8UC1);

Mat marker,marker_inner = processed(Rect(1, 1, processed.cols - 2, processed.rows - 2));
copyMakeBorder(marker_inner, marker, 1, 1, 1, 1, BORDER_ISOLATED | BORDER_CONSTANT, Scalar(255));

const auto lutIter0 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter0 : lut_zhang_iter0;
const auto lutIter1 = (thinningType == THINNING_GUOHALL) ? lut_guo_iter1 : lut_zhang_iter1;
do {
Expand Down
6 changes: 4 additions & 2 deletions modules/ximgproc/test/test_thinning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ TEST(ximgproc_Thinning, simple_ZHANGSUEN)
check_img = imread(dir + "cv/ximgproc/results/Thinning_ZHANGSUEN.png", IMREAD_GRAYSCALE);
EXPECT_EQ(0, cvtest::norm(check_img, dst, NORM_INF));

thinning(~src, dst, THINNING_ZHANGSUEN);
dst = ~src;
thinning(dst, dst, THINNING_ZHANGSUEN);

check_img = imread(dir + "cv/ximgproc/results/Thinning_inv_ZHANGSUEN.png", IMREAD_GRAYSCALE);
EXPECT_EQ(0, cvtest::norm(check_img, dst, NORM_INF));
Expand All @@ -34,7 +35,8 @@ TEST(ximgproc_Thinning, simple_GUOHALL)
check_img = imread(dir + "cv/ximgproc/results/Thinning_GUOHALL.png", IMREAD_GRAYSCALE);
EXPECT_EQ(0, cvtest::norm(check_img, dst, NORM_INF));

thinning(~src, dst, THINNING_GUOHALL);
dst = ~src;
thinning(dst, dst, THINNING_GUOHALL);

check_img = imread(dir + "cv/ximgproc/results/Thinning_inv_GUOHALL.png", IMREAD_GRAYSCALE);
EXPECT_EQ(0, cvtest::norm(check_img, dst, NORM_INF));
Expand Down

0 comments on commit 6246fad

Please sign in to comment.