Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/cpp/distrans.cpp
16337 views
1
#include <opencv2/core/utility.hpp>
2
#include "opencv2/imgproc.hpp"
3
#include "opencv2/imgcodecs.hpp"
4
#include "opencv2/highgui.hpp"
5
6
#include <stdio.h>
7
8
using namespace std;
9
using namespace cv;
10
11
int maskSize0 = DIST_MASK_5;
12
int voronoiType = -1;
13
int edgeThresh = 100;
14
int distType0 = DIST_L1;
15
16
// The output and temporary images
17
Mat gray;
18
19
// threshold trackbar callback
20
static void onTrackbar( int, void* )
21
{
22
static const Scalar colors[] =
23
{
24
Scalar(0,0,0),
25
Scalar(255,0,0),
26
Scalar(255,128,0),
27
Scalar(255,255,0),
28
Scalar(0,255,0),
29
Scalar(0,128,255),
30
Scalar(0,255,255),
31
Scalar(0,0,255),
32
Scalar(255,0,255)
33
};
34
35
int maskSize = voronoiType >= 0 ? DIST_MASK_5 : maskSize0;
36
int distType = voronoiType >= 0 ? DIST_L2 : distType0;
37
38
Mat edge = gray >= edgeThresh, dist, labels, dist8u;
39
40
if( voronoiType < 0 )
41
distanceTransform( edge, dist, distType, maskSize );
42
else
43
distanceTransform( edge, dist, labels, distType, maskSize, voronoiType );
44
45
if( voronoiType < 0 )
46
{
47
// begin "painting" the distance transform result
48
dist *= 5000;
49
pow(dist, 0.5, dist);
50
51
Mat dist32s, dist8u1, dist8u2;
52
53
dist.convertTo(dist32s, CV_32S, 1, 0.5);
54
dist32s &= Scalar::all(255);
55
56
dist32s.convertTo(dist8u1, CV_8U, 1, 0);
57
dist32s *= -1;
58
59
dist32s += Scalar::all(255);
60
dist32s.convertTo(dist8u2, CV_8U);
61
62
Mat planes[] = {dist8u1, dist8u2, dist8u2};
63
merge(planes, 3, dist8u);
64
}
65
else
66
{
67
dist8u.create(labels.size(), CV_8UC3);
68
for( int i = 0; i < labels.rows; i++ )
69
{
70
const int* ll = (const int*)labels.ptr(i);
71
const float* dd = (const float*)dist.ptr(i);
72
uchar* d = (uchar*)dist8u.ptr(i);
73
for( int j = 0; j < labels.cols; j++ )
74
{
75
int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1;
76
float scale = 1.f/(1 + dd[j]*dd[j]*0.0004f);
77
int b = cvRound(colors[idx][0]*scale);
78
int g = cvRound(colors[idx][1]*scale);
79
int r = cvRound(colors[idx][2]*scale);
80
d[j*3] = (uchar)b;
81
d[j*3+1] = (uchar)g;
82
d[j*3+2] = (uchar)r;
83
}
84
}
85
}
86
87
imshow("Distance Map", dist8u );
88
}
89
90
static void help()
91
{
92
printf("\nProgram to demonstrate the use of the distance transform function between edge images.\n"
93
"Usage:\n"
94
"./distrans [image_name -- default image is ../data/stuff.jpg]\n"
95
"\nHot keys: \n"
96
"\tESC - quit the program\n"
97
"\tC - use C/Inf metric\n"
98
"\tL1 - use L1 metric\n"
99
"\tL2 - use L2 metric\n"
100
"\t3 - use 3x3 mask\n"
101
"\t5 - use 5x5 mask\n"
102
"\t0 - use precise distance transform\n"
103
"\tv - switch to Voronoi diagram mode\n"
104
"\tp - switch to pixel-based Voronoi diagram mode\n"
105
"\tSPACE - loop through all the modes\n\n");
106
}
107
108
const char* keys =
109
{
110
"{help h||}{@image |../data/stuff.jpg|input image file}"
111
};
112
113
int main( int argc, const char** argv )
114
{
115
CommandLineParser parser(argc, argv, keys);
116
help();
117
if (parser.has("help"))
118
return 0;
119
string filename = parser.get<string>(0);
120
gray = imread(filename, 0);
121
if(gray.empty())
122
{
123
printf("Cannot read image file: %s\n", filename.c_str());
124
help();
125
return -1;
126
}
127
128
namedWindow("Distance Map", 1);
129
createTrackbar("Brightness Threshold", "Distance Map", &edgeThresh, 255, onTrackbar, 0);
130
131
for(;;)
132
{
133
// Call to update the view
134
onTrackbar(0, 0);
135
136
char c = (char)waitKey(0);
137
138
if( c == 27 )
139
break;
140
141
if( c == 'c' || c == 'C' || c == '1' || c == '2' ||
142
c == '3' || c == '5' || c == '0' )
143
voronoiType = -1;
144
145
if( c == 'c' || c == 'C' )
146
distType0 = DIST_C;
147
else if( c == '1' )
148
distType0 = DIST_L1;
149
else if( c == '2' )
150
distType0 = DIST_L2;
151
else if( c == '3' )
152
maskSize0 = DIST_MASK_3;
153
else if( c == '5' )
154
maskSize0 = DIST_MASK_5;
155
else if( c == '0' )
156
maskSize0 = DIST_MASK_PRECISE;
157
else if( c == 'v' )
158
voronoiType = 0;
159
else if( c == 'p' )
160
voronoiType = 1;
161
else if( c == ' ' )
162
{
163
if( voronoiType == 0 )
164
voronoiType = 1;
165
else if( voronoiType == 1 )
166
{
167
voronoiType = -1;
168
maskSize0 = DIST_MASK_3;
169
distType0 = DIST_C;
170
}
171
else if( distType0 == DIST_C )
172
distType0 = DIST_L1;
173
else if( distType0 == DIST_L1 )
174
distType0 = DIST_L2;
175
else if( maskSize0 == DIST_MASK_3 )
176
maskSize0 = DIST_MASK_5;
177
else if( maskSize0 == DIST_MASK_5 )
178
maskSize0 = DIST_MASK_PRECISE;
179
else if( maskSize0 == DIST_MASK_PRECISE )
180
voronoiType = 0;
181
}
182
}
183
184
return 0;
185
}
186
187