⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fnimage.cpp

📁 在人脸检测的基础之上,对嘴部的运动表情进行分析,进行语音模拟.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	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 + -