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

📄 imgproctest.cpp

📁 1394 接口视觉工具箱 (英文工具箱
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************************/
// Compile:   At the MATLAB prompt type:      'cc'
//
// fw-01-08
//
// processes a YUYV image (YCrCb 4:2:2  or  'yuv422')
//
/****************************************************************************************/

/* includes --------------------------------------------------------------------- */

#include <windows.h>
#include <string.h>			// strcmpi, strcpy
#include "cmvision.h"
#include "mex.h"
#include "matrix.h"


#define	 NDIMS  3                               // (maximum) dimension of the output data (RGB)
static unsigned int   dims[NDIMS];
static unsigned long  frameWidth, frameHeight;


// ######### CMVision ##########
static CMVision        vision;					/* CMVision class */
CMVision::region		*reg;

static rgb		      *img     = NULL;          /* dynamically allocated buffer... used by 'testClassify' */
static image_pixel	  *yuyvBuf = NULL;			/* pointer to converted input image (image_pixel, yuv422) */

#define	colourFilenameLength	100
static char			  colourFilename[colourFilenameLength];
static const char	  *defColourFilename = "testcolors.txt";	/* default colour file name */

// results of vision processing (struct myREG)
#define	defCOL	1			// default number of colours to be scanned for
#define	maxREG	10			// maximum number of regions to be recogniced per colour
#define minAREA	16			// minimum area of 'valid' regions

struct myREG {
	rgb					colour;
	unsigned int		nREG;
    unsigned int 		colourID;
	unsigned int		cen_x[maxREG];
	unsigned int		cen_y[maxREG];
	unsigned int		x1[maxREG];
	unsigned int		y1[maxREG];
	unsigned int		x2[maxREG];
	unsigned int		y2[maxREG];
} *retREG[CMV_MAX_COLORS];

const char		*fnames[4] = {"ColourID", "Colour", "nRegions", "Regions"};
int				foutdims[] = {0,0};			// dimensions of the output cell array


/* global variables, local to the DLL */
static mxArray	*FGretIMG;					/* optional display of image data -> need to create workspace variable */
static mxArray  *FGretIMGhandle;			/* optional display of image data -> now updating display via its handle */

static mxArray	*FGretCEN[maxREG];			/* optional display of centroid info -> need to create workspace variable */
static mxArray	*FGretBOX[maxREG];			/* optional display of boundary box  -> need to create workspace variable */

static double	myNaN;						// IEEE representation of 'NaN'
double			*pArgs;

static mxArray	*PatchArgs[3];				/* patch([NaN NaN NaN NaN NaN], [NaN NaN NaN NaN NaN], [0 0 0]) */
static mxArray	*PlotArgs[3];				/* plot([NaN NaN NaN NaN NaN], [NaN NaN NaN NaN NaN], 'w-') */

static mxArray	*SetArgStrings[4];			/* set command property: 'XData', 'YData', 'FaceColor', 'CData' */
static mxArray	*SetArgs[3];





/* local functions -------------------------------------------------------- */

//----------------------------------------------------------
// additional CMVision functions
//----------------------------------------------------------


// taken from CMU driver: ...\1394CamRGB.cpp
#define CLAMP_TO_UCHAR(a) ((unsigned char)((a) < 0 ? 0 : ((a) > 255 ? 255 : (a))))


//----------------------------------------------------------
yuv rgb_to_yuv(unsigned char r, unsigned char g, unsigned char b) {
	
	yuv	c;
	
	//c.y = CLAMP_TO_UCHAR(0.3*r + 0.5881*g + 0.1118*b);
	//c.u = CLAMP_TO_UCHAR(-0.15*r - 0.2941*g + 0.3882*b + 128);
	//c.v = CLAMP_TO_UCHAR(0.35*r - 0.2941*g - 0.0559*b + 128);
	c.y = CLAMP_TO_UCHAR((unsigned int)(0.3*r + 0.5881*g + 0.1118*b));
	c.u = CLAMP_TO_UCHAR((unsigned int)(-0.15*r - 0.2941*g + 0.3882*b + 128));
	c.v = CLAMP_TO_UCHAR((unsigned int)(0.35*r - 0.2941*g - 0.0559*b + 128));
	
	return c;
}
//----------------------------------------------------------


//----------------------------------------------------------
rgb yuv_to_rgb(unsigned char y, unsigned char u, unsigned char v) {
	
	
#ifdef ERASE________________________________________________
/* 
* replaced by the equivalent calculation found in the CMU driver which 
* uses integer maths only (-> higher performance)
* fw-01-08
	*/
	
	int U, V;
	rgb	c;
	
	U = (int)(2*u - 256);
	V = (int)(2*v - 256);
	
	c.red   = CLAMP_TO_UCHAR(y + V);
	c.green = CLAMP_TO_UCHAR((int)(y - 0.51*V - 0.19*U));
	c.blue  = CLAMP_TO_UCHAR(y + U);
	
#endif  /* ERASE_____________________________________________ */
	
	
	/* 
	* in line with the CMU driver...
	*/
	
	long	U, V, deltaG;
	rgb	c;
	
	U = u - 128;
	V = v - 128;
	
	deltaG = (12727 * U + 33384 * V);
	deltaG += (deltaG > 0 ? 32768 : -32768);
	deltaG >>= 16;
	
	c.red   = CLAMP_TO_UCHAR( y + V );
	c.green = CLAMP_TO_UCHAR( y - deltaG );
	c.blue  = CLAMP_TO_UCHAR( y + U );
	
	return c;
	
}
//----------------------------------------------------------



//----------------------------------------------------------
void convYUYV_2_RGB(rgb *dest, yuv422 *src) {
	
	unsigned long i;
	yuv422	p;
	
	//unsigned long size = dims[0]*processFrameNumPix/2;	// 2 pixels per yuv422 packet (YUYV)
	unsigned long size = frameHeight*frameWidth/2;		// 2 pixels per yuv422 packet (YUYV)
	
	for(i=0; i<size; i++) {
		p = src[i];
		dest[2*i + 0] = yuv_to_rgb(p.y1, p.u, p.v);
		dest[2*i + 1] = yuv_to_rgb(p.y2, p.u, p.v);
	}
	
}
//----------------------------------------------------------



//----------------------------------------------------------
void convRGB_2_YUYV(image_pixel *dst, unsigned char *src) {
	
	unsigned int		row, col, k;
	yuv					myYUV[2];		// intermediate result
	
	
	k = 0;
	for(row=0; row<frameHeight; row++) {
		for(col = 0; col<frameWidth-1; col+=2, k++) {
			
#ifdef ERASE
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | R = %-3d\n", row, col, row + col*frameHeight + 0*frameWidth*frameHeight, src[row + col*frameHeight + 0*frameWidth*frameHeight]);
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | G = %-3d\n", row, col, row + col*frameHeight + 1*frameWidth*frameHeight, src[row + col*frameHeight + 1*frameWidth*frameHeight]);
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | B = %-3d\n", row, col, row + col*frameHeight + 2*frameWidth*frameHeight, src[row + col*frameHeight + 2*frameWidth*frameHeight]);
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | R = %-3d\n", row, col+1, row + (col+1)*frameHeight + 0*frameWidth*frameHeight, src[row + (col+1)*frameHeight + 0*frameWidth*frameHeight]);
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | G = %-3d\n", row, col+1, row + (col+1)*frameHeight + 1*frameWidth*frameHeight, src[row + (col+1)*frameHeight + 1*frameWidth*frameHeight]);
			mexPrintf("row = %-3d | col = %-3d | idx = %-3d | B = %-3d\n", row, col+1, row + (col+1)*frameHeight + 2*frameWidth*frameHeight, src[row + (col+1)*frameHeight + 2*frameWidth*frameHeight]);
#endif

			
			/* MATLAB RGB -> YUV */
			myYUV[0]  = rgb_to_yuv( src[row + col*frameHeight + 0*frameWidth*frameHeight], \
									src[row + col*frameHeight + 1*frameWidth*frameHeight], \
									src[row + col*frameHeight + 2*frameWidth*frameHeight]  );
			myYUV[1]  = rgb_to_yuv( src[row + (col+1)*frameHeight + 0*frameWidth*frameHeight], \
									src[row + (col+1)*frameHeight + 1*frameWidth*frameHeight], \
									src[row + (col+1)*frameHeight + 2*frameWidth*frameHeight]  );
			
			/* YUV -> YUYV */
			dst[k].u  = (unsigned char)((myYUV[0].u + myYUV[1].u) >> 1);	// u
			dst[k].y1 = myYUV[0].y;											// y1
			dst[k].v  = (unsigned char)((myYUV[0].v + myYUV[1].v) >> 1);	// u
			dst[k].y2 = myYUV[1].y;											// y1

			
		}
	}
	
	//mexPrintf("yuyv buffer contains %d elements\n", k);
	
}
//----------------------------------------------------------



/* mySetupVision ============================================================= */
static void mySetupVision(unsigned int Wx, unsigned int Wy) {
    
	
    /* ensure that we only allocate memory if it hasn't been done yet... */
    if(yuyvBuf == NULL) {
        
		/* dynamically allocate memory for conversion buffers (CMVISION) */
		yuyvBuf = new image_pixel[Wx/2*Wy];
		//mexPrintf("yuyvBuf = %08x\n", yuyvBuf);
		
		img     = new rgb[Wx*Wy];
		//mexPrintf("img = %08x\n", img);
		
		// initialize class 'vision' (CMVision)
		if(!vision.initialize(Wx, Wy))
			mexErrMsgTxt("Vision init failed.\n");
        
		vision.loadOptions(colourFilename);
		vision.enable(CMV_DENSITY_MERGE);
        
	} else {
        
		/* CAMERA_STOP request has been issued */
		
		// destroy class 'vision'
		vision.close();
		
		/* destroy dynamically allocated buffer for 'yuyv' data */
		if(yuyvBuf != NULL) {
			delete yuyvBuf;
			yuyvBuf = NULL;
			//mexPrintf("yuyv buffer destroyed.\n");
		}
		
		/* destroy dynamically allocated buffer for 'img' data (output) */
		if(img != NULL) {
			delete img;
			img = NULL;
			//mexPrintf("img buffer destroyed.\n");
		}
		
    }
    
} /* mySetupVision ============================================================ */



/* mexFunction ============================================================= */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	
	mxArray		    *pArray;            		/* output data */
	unsigned char	*MATbuf;            		/* pointer to MATLAB memory */
	
	int				i, j;
	
	// ######### CMVision ##########
	int				numCOL, maxCOL;                 // number of detected colours
	int				numREG;
	int				COLIDs[CMV_MAX_COLORS];			// list of colour IDs to be scanned for
	int				COLdetected[CMV_MAX_COLORS];	// list of detected colour IDs
    
	// return detected coordinates in a structure
	mxArray			*fout;
	double			*pfout;
	int				fi;							// field index
    
	// input image: rgb
	const int			*inDims;				// dimensions of the input image (rgb)
	
	
    /************************************************************************/
	/* Check for proper number of input and output arguments 				*/
    /************************************************************************/
	
	if (!(nlhs==1 && (nrhs==1 || nrhs==2 || nrhs==3))) {
		
		mexErrMsgTxt("Usage:   Region_StructureArray = imgProc(RGBimage [, 'colour_filename'][, colour_list])\n    " \
			"    default colour file: testcolors.txt\n" );
		
	}
	else {
		
		// defaults
		strcpy(colourFilename, defColourFilename);
		maxCOL			= defCOL;			// default: just one colour
		COLIDs[0]		= 0;				// default colour '0'
		
		/* get 'RGBimage' parameter (always required) */
		MATbuf = (unsigned char*)mxGetData(prhs[0]);
		
		/* optional RHS: colour file name */
		if(nrhs >= 2) {
			mxGetString(prhs[1], colourFilename, colourFilenameLength);
			//mexPrintf("colour file: %s\n", colourFilename);
		}
		
		/* optional RHS: list of colours to be scanned for */
		if(nrhs >= 3) {
			
			/* get list of colours */
			if(!mxIsEmpty(prhs[2])) {
				
				if(!mxIsNumeric(prhs[2]) && !mxIsComplex(prhs[2]))
					mexErrMsgTxt("The specified colour list has to be a vector with up to 16 colour IDs\n");
				
				maxCOL = (unsigned int)mxGetNumberOfElements(prhs[2]);
				if(maxCOL > CMV_MAX_COLORS) {
					mexWarnMsgTxt("Too many colours specified. Reducing to maximum permitted (32)\n");
					maxCOL = CMV_MAX_COLORS;
				}
				
				// read colour vector
				pfout = mxGetPr(prhs[2]);
				for(fi=0; fi<maxCOL; fi++) {
					
					COLIDs[fi] = (unsigned int)(*(pfout+fi))-1;
					
					if((COLIDs[fi] < 0) || (COLIDs[fi] >= CMV_MAX_COLORS))
						mexErrMsgTxt("Colour(s) outside the valid range (1 ... 32).\n");
				}
				
			}
			
		}
		
	}
	
	
	/* determine image size */
	inDims      = mxGetDimensions(prhs[0]);
	frameHeight = (unsigned long)inDims[0];		// rows
	frameWidth  = (unsigned long)inDims[1];		// columns
	
	/* ensure minimum width and height (to avoid crashes) */
	if(frameWidth < 2 || frameHeight < 1) {

		// input image size is too small
		mexErrMsgTxt("Size of provided RGB image is too small (minimum: 2 x 1 pixels).\n");

	}


	/* vision algorithms are yuyv based  --  won't work if 'frameWidth' is an odd number 
	   (need 2 RGB pixels to form one yuyv pixel)  ->  adjust width, if required  */
	if((frameWidth%2) == 1) {

		mexPrintf("Reducing width by one pixel to make frameWidth become an even number\n");
		frameWidth--;

	}
	
	//mexPrintf("frameWidth  = %d\n", frameWidth);
	//mexPrintf("frameHeight = %d\n", frameHeight);
	
	/* allocate necessary memory... */
	mySetupVision(frameWidth, frameHeight);
	
	// convert RGB image to YUYV equivalent
	convRGB_2_YUYV(yuyvBuf, MATbuf);
	//mexPrintf("RGB image converted to yuyv.\n");
	
	// process image data
	//mexPrintf("before process.\n");
	vision.processFrame(yuyvBuf);
	//mexPrintf("after process.\n");
	
	{
		unsigned int	row, col;
		
		//mexPrintf("Before 'create FGretIMG'...\n");
		/* create numeric array FGretIMG (used to display the image) */
		dims[0] = frameHeight;
		dims[1] = frameWidth;
		dims[2] = 3;
		
		/* create a MATLAB array with 'iWidth' columns, 'iHeight' rows, 'real numbers'	*/
		FGretIMG = mxCreateNumericArray(NDIMS, (int const *)&dims[0], mxUINT8_CLASS, mxREAL);
		//mexPrintf("After 'create FGretIMG'.\n");
		
		/* ensure that MATLAB doesn't free data associated with FGretIMG (between subsequent calls to mdl-functions) */
		//mexMakeArrayPersistent(FGretIMG);		/* IMPORTANT!! (for Simulink only, FW-03-03) */

		/* get pointer to data area, can reuse pointer variable MATbuf here (input data has already been copied to yuyv buffer...) */
		MATbuf = (unsigned char *)mxGetData(FGretIMG);
		
		// convert raw yuv422 image to RGB
		convYUYV_2_RGB(img, (yuv422 *)yuyvBuf);
		//mexPrintf("image converted to RGB\n");
		
		// copy RGB to the MATLAB buffer...
		for(row=0; row<frameHeight; row++) {
			for(col=0; col<frameWidth; col++) {
				
				MATbuf[row+col*frameHeight+0*frameWidth*frameHeight] = img[row*frameWidth+col].red;
				MATbuf[row+col*frameHeight+1*frameWidth*frameHeight] = img[row*frameWidth+col].green;
				MATbuf[row+col*frameHeight+2*frameWidth*frameHeight] = img[row*frameWidth+col].blue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -