mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.5 KiB
164 lines
4.5 KiB
#include <opencv2/imgproc/imgproc.hpp> |
|
#include <opencv2/highgui/highgui.hpp> |
|
|
|
#include <stdio.h> |
|
|
|
using namespace cv; |
|
|
|
void help() |
|
{ |
|
printf("\nProgram to demonstrate the use of the distance transform function between edge images.\n" |
|
"Usage:\n" |
|
"./distrans [image_name -- default image is stuff.jpg]\n" |
|
); |
|
printf( "\nHot keys: \n" |
|
"\tESC - quit the program\n" |
|
"\tC - use C/Inf metric\n" |
|
"\tL1 - use L1 metric\n" |
|
"\tL2 - use L2 metric\n" |
|
"\t3 - use 3x3 mask\n" |
|
"\t5 - use 5x5 mask\n" |
|
"\t0 - use precise distance transform\n" |
|
"\tv - switch Voronoi diagram mode on/off\n" |
|
"\tSPACE - loop through all the modes\n" ); |
|
} |
|
|
|
int maskSize0 = CV_DIST_MASK_5; |
|
bool buildVoronoi = false; |
|
int edgeThresh = 100; |
|
int distType0 = CV_DIST_L1; |
|
|
|
// The output and temporary images |
|
Mat gray; |
|
|
|
// threshold trackbar callback |
|
void onTrackbar( int, void* ) |
|
{ |
|
static const Scalar colors[] = |
|
{ |
|
Scalar(0,0,0), |
|
Scalar(255,0,0), |
|
Scalar(255,128,0), |
|
Scalar(255,255,0), |
|
Scalar(0,255,0), |
|
Scalar(0,128,255), |
|
Scalar(0,255,255), |
|
Scalar(0,0,255), |
|
Scalar(255,0,255) |
|
}; |
|
|
|
int maskSize = buildVoronoi ? CV_DIST_MASK_5 : maskSize0; |
|
int distType = buildVoronoi ? CV_DIST_L2 : distType0; |
|
|
|
Mat edge = gray >= edgeThresh, dist, labels, dist8u; |
|
|
|
if( !buildVoronoi ) |
|
distanceTransform( edge, dist, distType, maskSize ); |
|
else |
|
distanceTransform( edge, dist, labels, distType, maskSize ); |
|
|
|
if( !buildVoronoi ) |
|
{ |
|
// begin "painting" the distance transform result |
|
dist *= 5000; |
|
pow(dist, 0.5, dist); |
|
|
|
Mat dist32s, dist8u1, dist8u2; |
|
|
|
dist.convertTo(dist32s, CV_32S, 1, 0.5); |
|
dist32s &= Scalar::all(255); |
|
|
|
dist32s.convertTo(dist8u1, CV_8U, 1, 0); |
|
dist32s *= -1; |
|
|
|
dist32s += Scalar::all(255); |
|
dist32s.convertTo(dist8u2, CV_8U); |
|
|
|
Mat planes[] = {dist8u1, dist8u2, dist8u2}; |
|
merge(planes, 3, dist8u); |
|
} |
|
else |
|
{ |
|
dist8u.create(labels.size(), CV_8UC3); |
|
for( int i = 0; i < labels.rows; i++ ) |
|
{ |
|
const int* ll = (const int*)labels.ptr(i); |
|
const float* dd = (const float*)dist.ptr(i); |
|
uchar* d = (uchar*)dist8u.ptr(i); |
|
for( int j = 0; j < labels.cols; j++ ) |
|
{ |
|
int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1; |
|
int b = cvRound(colors[idx][0]); |
|
int g = cvRound(colors[idx][1]); |
|
int r = cvRound(colors[idx][2]); |
|
d[j*3] = (uchar)b; |
|
d[j*3+1] = (uchar)g; |
|
d[j*3+2] = (uchar)r; |
|
} |
|
} |
|
} |
|
|
|
imshow("Distance Map", dist8u ); |
|
} |
|
|
|
int main( int argc, char** argv ) |
|
{ |
|
char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg"; |
|
gray = imread(filename, 0); |
|
if(gray.empty()) |
|
{ |
|
help(); |
|
return -1; |
|
} |
|
|
|
help(); |
|
namedWindow("Distance Map", 1); |
|
createTrackbar("Brightness Threshold", "Distance Map", &edgeThresh, 255, onTrackbar, 0); |
|
|
|
for(;;) |
|
{ |
|
// Call to update the view |
|
onTrackbar(0, 0); |
|
|
|
int c = cvWaitKey(0); |
|
|
|
if( (char)c == 27 ) |
|
break; |
|
|
|
if( (char)c == 'c' || (char)c == 'C' ) |
|
distType0 = CV_DIST_C; |
|
else if( (char)c == '1' ) |
|
distType0 = CV_DIST_L1; |
|
else if( (char)c == '2' ) |
|
distType0 = CV_DIST_L2; |
|
else if( (char)c == '3' ) |
|
maskSize0 = CV_DIST_MASK_3; |
|
else if( (char)c == '5' ) |
|
maskSize0 = CV_DIST_MASK_5; |
|
else if( (char)c == '0' ) |
|
maskSize0 = CV_DIST_MASK_PRECISE; |
|
else if( (char)c == 'v' ) |
|
buildVoronoi = !buildVoronoi; |
|
else if( (char)c == ' ' ) |
|
{ |
|
if( buildVoronoi ) |
|
{ |
|
buildVoronoi = false; |
|
maskSize0 = CV_DIST_MASK_3; |
|
distType0 = CV_DIST_C; |
|
} |
|
else if( distType0 == CV_DIST_C ) |
|
distType0 = CV_DIST_L1; |
|
else if( distType0 == CV_DIST_L1 ) |
|
distType0 = CV_DIST_L2; |
|
else if( maskSize0 == CV_DIST_MASK_3 ) |
|
maskSize0 = CV_DIST_MASK_5; |
|
else if( maskSize0 == CV_DIST_MASK_5 ) |
|
maskSize0 = CV_DIST_MASK_PRECISE; |
|
else if( maskSize0 == CV_DIST_MASK_PRECISE ) |
|
buildVoronoi = true; |
|
} |
|
} |
|
|
|
return 0; |
|
}
|
|
|