Commit 65ffe927 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #751 from StevenPuttemans:add_thinning_algorithm

parents 90fe437e 5f816bb4
......@@ -104,6 +104,16 @@ CV_EXPORTS_W void niBlackThreshold( InputArray _src, OutputArray _dst,
double maxValue, int type,
int blockSize, double delta );
/** @brief Applies a binary blob thinning operation, to achieve a skeletization of the input image.
The function transforms a binary blob image into a skeletized form using the technique of Zhang-Suen.
@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.
*/
CV_EXPORTS_W void thinning( InputArray src, OutputArray dst);
//! @}
}
......
#include "precomp.hpp"
using namespace std;
namespace cv {
namespace ximgproc {
// Applies a thinning iteration to a binary image
static void thinningIteration(Mat img, int iter){
Mat marker = Mat::zeros(img.size(), CV_8UC1);
for (int i = 1; i < img.rows-1; i++)
{
for (int j = 1; j < img.cols-1; j++)
{
uchar p2 = img.at<uchar>(i-1, j);
uchar p3 = img.at<uchar>(i-1, j+1);
uchar p4 = img.at<uchar>(i, j+1);
uchar p5 = img.at<uchar>(i+1, j+1);
uchar p6 = img.at<uchar>(i+1, j);
uchar p7 = img.at<uchar>(i+1, j-1);
uchar p8 = img.at<uchar>(i, j-1);
uchar p9 = img.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;
}
}
img &= ~marker;
}
// Apply the thinning procedure to a given image
void thinning(InputArray input, OutputArray output){
Mat processed = input.getMat().clone();
// Enforce the range of the input image to be in between 0 - 255
processed /= 255;
Mat prev = Mat::zeros(processed.size(), CV_8UC1);
Mat diff;
do {
thinningIteration(processed, 0);
thinningIteration(processed, 1);
absdiff(processed, prev, diff);
processed.copyTo(prev);
}
while (countNonZero(diff) > 0);
processed *= 255;
output.assign(processed);
}
} //namespace ximgproc
} //namespace cv
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment