📄 fnimage.cpp
字号:
for ( j = 0; j < a.ysize ; ++j)
{
for (i = 0; i < a.xsize ; ++i)
{
if (a(j,i) < min)
{
min = a(j,i);
b(0) = i;
b(1) = j;
}
}
}
return min;
}
//---------------------------------
void resize(matrix &im, int k, int l)
//---------------------------------
{
// resize the matrix image to new dimensions
// im.ysize = k, im.xsize = l and chop the
// extra elements
matrix temp = im;
int i,j;
if ((im.ysize !=0) && (im.xsize!=0))
{
delete[] im.elem;
delete[] im.rowptr;
}
im.ysize=k;
im.xsize=l;
im.elem = new double [im.ysize*im.xsize];
im.rowptr = new double* [im.ysize];
for( i=0; i < im.ysize; i++)
im.rowptr[i]= im.elem + i*im.xsize;
int ysi = temp.ysize < im.ysize ? temp.ysize : im.ysize;
int xsi = temp.xsize < im.ysize ? temp.xsize : im.xsize;
for( j = 0; j < ysi; ++j)
for( i = 0; i < xsi; ++i)
im(j,i) = temp(j,i);
}
//----------------------------------------------------------------------------------------
void rgbToHsv( double r, double g, double b, double& h, double& s, double& v)
{
// Maps any set of RGB values to its corresponding HSV values
// Assumes r, g, and b to be in range [0,255]
// Returns h, s, v in range [0, 1]
double min, max, delta;
int NO_HUE = 1;
r = r / 255;
g = g / 255;
b = b / 255;
max = fMath.Max( r, fMath.Max(g, b));
min = fMath.Min( r, fMath.Min(g, b));
delta = max - min;
v = max;
if ( max != 0 )
s = delta / max;
else
s = 0.0;
if ( s == 0.0)
h = NO_HUE;
else
{
if ( r == max)
h = ( g - b) / delta;
else
{
if ( g == max)
h = 2 + ( b - r) / delta;
else
{
if ( b == max)
h = 4+(r - g) / delta;
} // else
} // else
h = h * 60.0;
if ( h < 0)
h = h / 360.0;
} // else
}
//-----------------------------------------------------------------------------------------
void hsvToRgb( double h, double s, double v, double& red, double& green, double& blue)
{
// Maps any set of HSV values to its corresponding RGB values
// Assumes h, s, v to be int range [0, 1]
// Returns r, g, b in range [0, 255]
ASSERT( (0.0<=h)&&(h<=1.0) && (0.0<=s)&&(s<=1.0) && (0.0<=v)&&(v<=1.0) );
double a, b, c, f;
int i;
if ( s == 0.0 ) // must be grayscale
{
red = v;
green = v;
blue = v;
} // if
else
{
if ( h == 1.0)
h = 0.0;
h = h * 6.0;
i = (int) floor(h);
f = h - i;
a = v * ( 1 - s);
b = v * ( 1 - ( s * f));
c = v * ( 1 - ( s * (1 - f)));
switch (i)
{
case 0:
red = v; green = c; blue = a;
break;
case 1:
red = b; green = v; blue = a;
break;
case 2:
red = a; green = v; blue = c;
break;
case 3:
red = a; green = b; blue = v;
break;
case 4:
red = c; green = a; blue = v;
break;
case 5:
red = v; green = a; blue = b;
break;
} // switch
red = floor( 0.5 + red * 255); // 0.5 sonradan eklendi
green = floor( 0.5 + green * 255); // 0.5 sonradan eklendi
blue = floor( 0.5 + blue * 255); // 0.5 sonradan eklendi
} // else
}
//---------------------------------------------------------------------------
matrix MedianFilter(matrix& image, int windowsize)
{
ASSERT( windowsize >= 3 && image.xsize > 0 && image.ysize > 0 && image.numbands == 1);
// if windowsize is even make it odd
int half;
if ( windowsize%2 == 0)
{
half = windowsize / 2;
windowsize++;
}
else
half = ( windowsize - 1) / 2;
register int j, i, m, n, u, v, k;
int total = windowsize * windowsize;
double *Pixels = new double [total];
FnMath math;
matrix FilteredImage = image;
for ( j = 0; j < image.ysize; ++j)
{
for( i = 0; i < image.xsize; ++i)
{
for ( m = -half, k = 0; m <= half; ++m)
{
u = j + m;
if( u < 0) u = 0;
else if( u >= image.ysize) u = image.ysize - 1;
for( n = -half; n <= half; ++n, k++)
{
v = i + n;
if( v < 0) v = 0;
else if( v >= image.xsize) v = image.xsize - 1;
Pixels[ k] = image( u, v);
} // for n
} // for m
math.sort( total, Pixels);
FilteredImage( j, i) = Pixels[ total / 2]; // choose the median value
} // for i
} // for j
delete[] Pixels;
return FilteredImage;
}
//----------------------------------------------------------------------------
matrix thin_1 (matrix& x, int start_x, int start_y, int end_x, int end_y)
{
// N1 : start_y
// M1 : start_x
// N2 : end_y
// M2 : end_x
// One pass thinning algorithm
// Satisfies the following contraints:
// 1) Maintain connectivity at each iteration. Do not remove border pixels
// that may cause discontinuities.
// 2) Do not shorten the end of thinned shape limbs.
//
// x: input image, consists of 255s and 0s. 0 denotes an edge pixel.
// N1, M1: start coordinates
// N2, M2: end coordinates
// From the book Digital Image Processing Algorithms, I.Pitas, 1993.
// A modification of the algorithm described in
// M.G.Fairhurst, Computer Vision for Robotic Systems, Prentice-hall,1988.
int k, l, i, j, count = 0, y[9], trans = 0, m, OK = 1, u, v;
int ct = 0, N1, N2, M1, M2;
N1 = start_y;
N2 = end_y;
M1 = start_x;
M2 = end_y;
matrix out = x;
do {
OK = 1;
for ( k = N1+1; k < N2-1; k ++)
{
for ( l = M1+1; l < M2-1; l++)
{
if (out(k, l) == 0)
{
// count the number of edge pixels in a 3x3 window
count = 0;
for ( i = -1; i <= 1; i++)
{
for ( j = -1; j <= 1; j++)
{
u = k + i;
v = l + j;
u = (u < 0) ? 0 : u;
u = (u > N2 - 2) ? (N2 - 2) : u;
v = (v < 0) ? 0 : v;
v = (v > N2 - 2) ? (N2 - 2) : v;
if ( out(u, v) == 0)
count++;
}
}
if (( count > 2) && (count < 8))
{
// count the number of transitions
y[0] = (int) out(k-1,l-1);
y[1] = (int) out(k-1,l);
y[2] = (int) out(k-1,l+1);
y[3] = (int) out(k,l+1);
y[4] = (int) out(k+1,l+1);
y[5] = (int) out(k+1,l);
y[6] = (int) out(k+1,l-1);
y[7] = (int) out(k,l-1);
y[8] = (int) out(k-1,l-1);
trans = 0;
for ( m = 0; m <= 7; m++)
{
if (y[m] == 255 && y[m+1] == 0)
trans++;
}
if ( trans == 1)
{
out(k,l) = 255;
OK = 0;
}
} // if
} // if out == 0
} // for l
} // for k
} while ( OK == 0);
return out;
}
//-----------------------------------------------------------------------------------------
matrix thin_2 (matrix& InImage, int startx, int starty, int endx, int endy)
{
// Two pass thinning algorithm
// x: input image, consists of 255s and 0s. 0 denotes an edge pixel.
// N1, M1: start coordinates
// N2, M2: end coordinates
// From the book Digital Image Processing Algorithms, I.Pitas, 1993.
int k, l, i, j, count = 0, trans = 0, m, OK = 1, turn = 0;
int y[9],
N1, N2, M1, M2;
matrix z; // z is a flag image
matrix x = InImage;
N1 = starty;
N2 = endy;
M1 = startx;
M2 = endx;
do{
OK = 1;
turn = (turn + 1) % 2;
// clear the flag buffer
z = zeros(N2 - N1, M2 - M1);
for ( k = N1 + 1; k < N2 - 1; k++)
{
for ( l = M1 + 1; l < M2 - 1; l++)
{
if ( x(k,l) == 0)
{
// count the number of edge pixels in 3x3 window
count = 0;
for ( i = -1; i <= 1; i++)
{
for ( j = -1; j <= 1; j++)
if ( x( k + i, l + j) == 0)
count++;
}
if (( count > 2) && (count < 8))
{
// count the number of transitions
y[0] = (int) x(k-1,l-1);
y[1] = (int) x(k-1,l);
y[2] = (int) x(k-1,l+1);
y[3] = (int) x(k,l+1);
y[4] = (int) x(k+1,l+1);
y[5] = (int) x(k+1,l);
y[6] = (int) x(k+1,l-1);
y[7] = (int) x(k,l-1);
y[8] = (int) x(k-1,l-1);
trans = 0;
for ( m = 0; m <= 7; m++)
{
if (y[m] == 255 && y[m+1] == 0)
trans++;
}
// flag current pixel to be deleted
if (trans == 1)
{
if ( turn == 0 && (y[3] == 0 || y[5] == 0 || (y[1] == 0 && y[7] == 0)))
{
z(k-N1,l-M1) = 1;
OK = 0;
}
else if ( turn == 1 && (y[1] == 0 || y[1] == 0 || (y[3] == 0 && y[5] == 0)))
{
z(k-N1, l-M1) = 1;
OK = 0;
}
}
}
}
} // for l
} // for k
// delete flagged pixels
for ( k = N1 + 1; k < N2-1; k++)
{
for ( l = M1 + 1; l < M2-1; l++)
{
if (z(k - N1, l - M1) == 1)
x(k, l) = 255;
}
}
} while (OK == 0);
return x;
}
//----------------------------------------------------------------------------------
matrix thin_4(matrix& InImage, int startx, int starty, int endx, int endy)
{
// remove the center pixel in a 3x3 box if the connectedness
// of the neighboring pixels are not affected.
int k, l, i, j, OK = 1, count = 0;
matrix x = InImage;
matrix box(3,3), b;
int NS = 4, N;
int *h = new int[NS];
do{
OK = 1;
// clear the flag buffer
for ( k = starty + 1; k < endy - 1; k++)
{
for ( l = startx + 1; l < endx - 1; l++)
{
if ( x(k,l) == 0)
{
count = 0;
for ( i = -1; i <= 1; i++)
{
for ( j = -1; j <= 1; j++)
{
if ( x( k + i, l + j) == 0)
count++;
if ( (i == 0) && (j == 0) )
box(j+1, i+1) = 0;
else
box(j+1, i+1) = (x( k+j, l+i) == 255) ? 0 : 255;
}
}
//if ( count < 8)
{
grass_label(box, b, N, h, NS, 0, 0, 3, 3);
if ( N == 1)
x(k, l) = 255;
}
} // if x == 0
} // for l
} // for k
// delete flagged pixels
} while (OK == 0);
delete[] h;
return x;
}
//------------------------------------------------------------------------
int grass_label(matrix& a, matrix& b, int& N, int* h, int NS, int N1, int M1,
int N2, int M2)
//------------------------------------------------------------------------
{
// Reference: Digital Image Processing Algorithms and Applications
// I.Pitas, page:301
// Subroutine for counting objects in a binary image
// inputs:
// a: binary input image (0 / 255) 255: edges
// N1, M1: start coordinates
// N2, M2: end coordinates
// outputs:
// b: output labeled image
// N: number of objects
// h: buffer to store object areas
// NS: maximum allowable number of objects (length of array h)
int i, j, number;
matrix inimage = a;
b = zeros(a.ysize, a.xsize);
for ( i = 0; i < NS; i++)
{
h[i] = 0;
}
number = 0;
for ( i = N1; i < N2; i++ )
{
for ( j = M1; j < M2; j++)
{
if ( inimage(j, i) == 255)
{
grass(inimage, b, j, i, number+1, h+number, N1, M1, N2, M2);
number++;
if ( number > NS)
{
N = number;
return 0;
}
}
}
}
N = number;
return 1;
}
//------------------------------------------------------------------------
int grass(matrix& a, matrix& b, int row, int col, int number, int* area,
int N1, int M1, int N2, int M2)
//------------------------------------------------------------------------
{
// Subroutine to clear a binary object that starts at
// (row, col) and calculates its area
// Inputs:
// a: input image
// row, col: pixel coordinates
// number: current object number
// N1, M1: start coordinates
// N2, M2: end coordinates
// Outputs:
// b: output image
// area: object area (in pixels)
int i, j;
a( row, col) = 0.0;
b( row, col) = number;
(*area)++;
for ( i = -1; i <= 1; i++)
{
for ( j = -1; j <= 1; j++)
{
if ( ((row+j) >= M1 ) && ((row+j) < M2) &&
((col+i) >= N1 ) && ((col+i) < N2) )
{
if (a(row+j,col+i) == 255)
grass(a,b,row+j,col+i,number,area,N1,M1,N2,M2);
}
}
}
return 1;
}
//----------------------------------------------------------------
matrix DeleteSmallSegments(matrix& b, int* h, int N, int th)
//----------------------------------------------------------------
{
ASSERT( N >= 1);
matrix outimage = 255 * ones(b.ysize, b.xsize);
int i, j, label;
for ( j = 0; j < b.ysize; j++)
{
for ( i = 0; i < b.xsize; i++)
{
label = (int) b(j, i);
if ( (label > 0) && ( h[label-1] > th) )
{
outimage(j, i) = 0;
}
}
}
return outimage;
}
//-----------------------------------------------------------------------------
matrix CleanEdgeMap( matrix& edges_in, int N1, int M1, int N2, int M2, int th)
//-----------------------------------------------------------------------------
{
int i, j;
matrix edges_out(edges_in.ysize, edges_in.xsize);
matrix b;
int N, NS = 5000;
int *h = new int [NS] ;
for ( j = 0; j < edges_out.ysize; j++)
{
for ( i = 0; i < edges_in.xsize; i++)
{
edges_out(j, i) = (edges_in(j, i) == 0) ? 255 : 0;
}
}
grass_label(edges_out, b, N, h, NS, N1, M1, N2, M2);
edges_out = DeleteSmallSegments(b, h, N, th);
delete [] h;
return edges_out;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -