capprocstereo2.cpp

来自「1394 接口视觉工具箱 (英文工具箱」· C++ 代码 · 共 1,884 行 · 第 1/4 页

CPP
1,884
字号
			requestedWidth  = (unsigned int)(mxGetScalar(prhs[5]));
			requestedHeight = (unsigned int)(mxGetScalar(prhs[6]));
		}
        
		/* optional: origin */
		if(nrhs == 9) {
			requestedOrigX  = (unsigned int)(mxGetScalar(prhs[7]));
			requestedOrigY  = (unsigned int)(mxGetScalar(prhs[8]));
		}
        
    }

    
    /* resize... if necessary */
    if(	currentMode != mode            || \
        currWidth   != requestedWidth  || \
		currHeight  != requestedHeight || \
		currOrigX   != requestedOrigX  || \
		currOrigY   != requestedOrigY     ) {
        

        /* stop acquisition - if currently ongoing */
		if(initCamera) {

			/* stop camera */
	        mySetupCamera(CAMERA_STOP);

			/* stop vision */
			mySetupVision(CAMERA_STOP, 0, 0);

		}


		/* (re)initialize camera */
        mySetupCamera(mode);


		/* set requested ORIGIN (X)  of the image to be returned to MATLAB */
		if(requestedOrigX >= 0 && requestedOrigX < frameWidth) {
			
			/* change of origin (X) */
			origX = requestedOrigX;
			
		} else {
			
			/* default origin (X) */
			origX = 0;
			//mexPrintf("Requested origin-x (%d) outside valid limits (0 ... %d). Using default origin (0).\n", requestedOrigX, frameWidth-1);
			
		}

		/* remember that the origin has been set */
		currOrigX = requestedOrigX;

		
		/* set requested WIDTH of the image to be returned to MATLAB */
		if(requestedWidth > 0 && requestedWidth <= frameWidth-origX) {
			
			/* requested width is valid -> reduce width of output array */
			dims[1] = requestedWidth;
			
		} else {

			/* requested width exceeds framewidth -> allocate as much as available */
			dims[1] = frameWidth - origX;

		}
		
		/* remember that the width has been set */
		currWidth = requestedWidth;
			

		/* set requested ORIGIN (Y)  of the image to be returned to MATLAB */
		if(requestedOrigY >= 0 && requestedOrigY < frameHeight) {
			
			/* change of origin (Y) */
			origY = requestedOrigY;
			
		} else {
			
			/* default origin (X) */
			origY = 0;
			//mexPrintf("Requested origin-y (%d) outside valid limits (0 ... %d). Using default origin (0).\n", requestedOrigY, frameHeight-1);
			
		}
		
		/* remember that the origin has been set */
		currOrigY = requestedOrigY;


		/* set requested HEIGHT of the image to be returned to MATLAB */
		if(requestedHeight > 0 && requestedHeight <= frameHeight-origY) {
			
			/* requested height is valid -> reduce height of output array */
			dims[0] = requestedHeight;
			
		} else {

			/* requested height exceeds frameheight -> allocate as much as available */
			dims[0] = frameHeight - origY;

		}

		/* remember that the height has been set */
		currHeight = requestedHeight;
			
		
		#ifdef ERASE
		// debug only
		mexPrintf("requestedWidth  = %d\n", requestedWidth);
		mexPrintf("currWidth       = %d\n", currWidth);
		mexPrintf("dims[1]         = %d\n", dims[1]);
		mexPrintf("requestedHeight = %d\n", requestedHeight);
		mexPrintf("currHeight      = %d\n", currHeight);
		mexPrintf("dims[0]         = %d\n", dims[0]);
		mexPrintf("requestedOrigX  = %d\n", requestedOrigX);
		mexPrintf("currOrigX       = %d\n", currOrigY);
		mexPrintf("origX           = %d\n", origX);
		mexPrintf("requestedOrigY  = %d\n", requestedOrigY);
		mexPrintf("currOrigY       = %d\n", currOrigY);
		mexPrintf("origY           = %d\n", origY);
		#endif


		/* adjust 'width' (dims[1]) to be an integer multiple of the camera element width (3 for RGB, etc.) */
		switch(mode) {
				
			case CAMERA_YUV444_160x120:
			case CAMERA_RGB8_640x480:
				
				/* YUV, RGB -> each pixel is 3 bytes */
				pixPerPacket = 1;
				packetSize   = 3;
	
				break;
				
			case CAMERA_YUV422_320x240:
			case CAMERA_YUV422_640x480:
				
				/* UYVY -> pixel pairs are represented by 4 bytes */
				pixPerPacket = 2;
				packetSize   = 4;
	
				break;
				
			case CAMERA_YUV411_640x480:
				
				/* YUV411 (UYYVYY) -> 4 pixel are represented by 6 bytes */
				pixPerPacket = 4;
				packetSize   = 6;
	
				break;
				
			case CAMERA_Y8_640x480:
				
				/* Y -> each byte is a pixel */
				pixPerPacket = 1;
				packetSize   = 1;
	
				break;
				
			case CAMERA_Y16_640x480:
				
				/* YY -> each pixel requires 2 bytes */
				pixPerPacket = 1;
				packetSize   = 2;
	
				break;
				
			default:

				// shouldn't be reached (assume RGB, just in case)
				pixPerPacket = 1;
				packetSize   = 3;
	
				break;
				
		} /* switch */

		// Determine beginning and end of the memory section to be processed 
		// (required by the 'convXXtoYY' methods above as these directly access the 'raw data' buffer 
		//  of the camera  --  width variable 'dims[1]' needs to be adjusted according to the number
		//  of pixels in the chosen processFrameWidth; the final output to MATLAB then further reduces 
		//  this number to the requested number of pixels (fine selection)
		//
		// EXAMPLE:  '3 pixels from pixel #4 on'	-> need two packets (y1-y4) & (y5-y10) 
		//											=> firstPacketStart = 0, lastPacketStart = 6, dims[0] = 12
		//			                  |      |  |
		//           _________________v  ____v__v_________ 
		//           --0--1--2--3--4--5---6--7--8--9-10-11--12-13--14-15--16--17
		//			 -u1-y1-y2-v1-y3-y4--u2-y5-y6-v2-y7-y8--u3-y9-y10-v3-y11-y12
		//
		firstPacketStart   = ((int)(origX/pixPerPacket) >= 0 ? (int)(origX/pixPerPacket) : 0 ) * packetSize;
		lastPacketStart    = ((int)((origX+dims[1]-1)/pixPerPacket) >= 0 ? (int)((origX+dims[1]-1)/pixPerPacket) : 0 ) * packetSize;
		processFrameWidth  = lastPacketStart - firstPacketStart + packetSize;
		processFrameNumPix = processFrameWidth / packetSize * pixPerPacket;
		packetOffsetX      = origX - (int)(origX/pixPerPacket)*pixPerPacket;

		// debugging stage...
		#ifdef ERASE
		if(mode != CAMERA_STOP) {
			mexPrintf("firstPacketStart   = %d\n", firstPacketStart);
			mexPrintf("lastPacketStart    = %d\n", lastPacketStart);
			mexPrintf("processFrameWidth  = %d\n", processFrameWidth);
			mexPrintf("processFrameNumPix = %d\n", processFrameNumPix);
			mexPrintf("requestedWidth     = %d\n", requestedWidth);
			mexPrintf("requestedOrigX     = %d\n", requestedOrigX);
			mexPrintf("origX              = %d\n", origX);
			mexPrintf("packetOffsetX      = %d\n", packetOffsetX);
		}
		#endif


		/* (re)initialize vision system with adjusted dimensions (CMVISION) */
		/* NOTE:  This now uses the adjusted number of pixels per row within the process frame 
		          (might be slightly bigger than the requested width (dims[1]) */
		mySetupVision(mode, processFrameNumPix /* width */, dims[0] /* height */);

    }
    

	/* acquire image -- make sure camera is actually running... */
    if(initCamera == 1) {
        
		/* loop through both cameras... */
		for(int cam=0; cam<2; cam++) {
		
			//mexPrintf("Capturing image\n");
			if(Camera[cam].CaptureImage() != CAM_SUCCESS)
				mexErrMsgTxt("Error during image capture.\n");
        

			/* -------------  CMVision  ------------- */
	

			/* convert current frame to the YUYV format (required by CMVISION) */
			convCurrentFrame2YUYV(cam, mode, yuyvBuf);
	
	
			// process image data  --  sets region info in 'vision', does not alter yuyvBuf
			vision.loadOptions(colourFilename[cam]);
			vision.processFrame((yuv422 *)yuyvBuf);
	
	
			// reset 'detected regions' list
			numCOL = 0;
			for(i=0; i<maxCOL; i++)  COLdetected[i] = -1;
	
			// scan regions with specified colour IDs
			for(i=0; i<maxCOL; i++) {
				
				reg = vision.getRegions(COLIDs[i]);
				
				// allocate memory to store data
				retREG[i] = (struct myREG *)mxCalloc(1, sizeof(struct myREG));
				
				// initialize structure
				retREG[i]->colourID = COLIDs[i];
							  //printf("-------------------------------\n");
							  //printf("colID: %d\n", retREG[i]->colourID);
	
				retREG[i]->colour = vision.getColorVisual(COLIDs[i]);
							  //printf("R|G|B: %3d|%3d|%3d\n", retREG[i]->colour.red,
							  //			     retREG[i]->colour.green,
							  //			     retREG[i]->colour.blue);
				
				numREG = 0;
				while(reg && reg->area>minAREA && numREG<maxREG) {

					retREG[i]->cen_x[numREG] = (unsigned int)reg->cen_x;
					retREG[i]->cen_y[numREG] = (unsigned int)reg->cen_y;
					retREG[i]->x1[numREG]    = (unsigned int)reg->x1;
					retREG[i]->y1[numREG]    = (unsigned int)reg->y1;
					retREG[i]->x2[numREG]    = (unsigned int)reg->x2;
					retREG[i]->y2[numREG]    = (unsigned int)reg->y2;
					
					mexPrintf("Area of region %d: %d\n", numREG, reg->area);
					mexPrintf("X1|Y1|X2|Y2: %3d|%3d|%3d|%3d\n", retREG[i]->x1[numREG], retREG[i]->y1[numREG],
						retREG[i]->x2[numREG], retREG[i]->y2[numREG]);
					
					retREG[i]->nREG = ++numREG;
					reg = reg->next;
					
				}
	
				// check if any regions were detected for this colour
				if(numREG) {
					// valid colour... (found at least one valid region)
					COLdetected[numCOL++] = i;      // corresponding colour ID (loop variable)
				}
			}
			
			/* -------------  CMVision  ------------- */
	
	
			/*************************************************************************/
			/* return regional information in form of a structure array		 */
			/*************************************************************************/
			if((pArray[cam] = mxCreateStructMatrix(numCOL, 1, 4, fnames)) == NULL)		// numCOL structures
				mexErrMsgTxt("Failure assigning stucture memory\n");
			
			// update 'ColourID' field...
			for (i=0; i<numCOL; i++)		// ... in all elements of the structure
			{
				// get index of the detected colour
				j = COLdetected[i];
				
				// create mxArray to store the colour information
				fout = mxCreateDoubleMatrix(1,1,mxREAL);		// colourID
				pfout = mxGetPr(fout);				// beginning of data area
				
				//printf("Updating colourID (%d)\n", j);
				// copy data
				*(pfout  ) =  (double)(retREG[j]->colourID);
				
				// update structure entry (field index: 0)
				mxSetFieldByNumber(pArray[cam], i, 0, fout);
			}
			//mexPrintf("Updated colourID\n");
	
	
			// update 'Colour' field...
			for (i=0; i<numCOL; i++)		// ... in all elements of the structure
			{
				// get index of the detected colour
				j = COLdetected[i];
	
				// create mxArray to store the colour information
				fout = mxCreateDoubleMatrix(1,3,mxREAL);		// R, G, B
				pfout = mxGetPr(fout);				// beginning of data area
				
				// copy data
				*(pfout  ) =  (double)(retREG[j]->colour.red)/255.0;
				*(pfout+1) =  (double)(retREG[j]->colour.green)/255.0;
				*(pfout+2) =  (double)(retREG[j]->colour.blue)/255.0;
				
				// update structure entry (field index: 0)
				mxSetFieldByNumber(pArray[cam], i, 1, fout);
			}
			//mexPrintf("Updated colour\n");
			
			
			// update 'nRegions' field...
			for (i=0; i<numCOL; i++)		// ... in all elements of the structure
			{
				// get index of the detected colour
				j = COLdetected[i];
	
				// create mxArray to store the number of valid regions found
				fout = mxCreateDoubleMatrix(1,1,mxREAL);
				pfout = mxGetPr(fout);				// beginning of data area
				
				// copy data
				*(pfout  ) =  (double)(retREG[j]->nREG);
			   
				// update structure entry (field index: 1)
				mxSetFieldByNumber(pArray[cam], i, 2, fout);
			}
			//mexPrintf("Updated nRegions\n");
			
			
			// update 'Regions' field...
			for (i=0; i<numCOL; i++)		// ... in all elements of the structure
			{
				// get index of the detected colour
				j = COLdetected[i];
	
				// create mxArray to store the colour information
				numREG = (unsigned int)(retREG[j]->nREG);
				
				if(numREG)
				{
					//printf(">> In numREG %d\n", i);
					//printf(">> numREG = %d\n", numREG);
					*((int*)foutdims) = 6;						// cen_x, cen_y, x, y, w, h
					foutdims[1] = (int)numREG;					// valid regions
					fout = mxCreateNumericArray(2, foutdims, mxDOUBLE_CLASS, mxREAL);
					pfout = mxGetPr(fout);						// beginning of data area
					
					// copy data
					for(fi=0; fi<numREG; fi++)
					{
						*(pfout+fi*6  ) =  (double)(retREG[j]->cen_x[fi]);
						*(pfout+fi*6+1) =  (double)(retREG[j]->cen_y[fi]);
						*(pfout+fi*6+2) =  (double)(retREG[j]->x1[fi]);
						*(pfout+fi*6+3) =  (double)(retREG[j]->y1[fi]);
						*(pfout+fi*6+4) =  (double)(retREG[j]->x2[fi]);
						*(pfout+fi*6+5) =  (double)(retREG[j]->y2[fi]);
						
						// update structure entry (field index: 2)
						mxSetFieldByNumber(pArray[cam],i,3,fout);
					}
				}
			}
			//mexPrintf("Updated Regions\n");
			
			// free dynamically allocated memory
			for(i=0; i<maxCOL; i++)	mxFree(retREG[i]);
			
			
			// return output array pointer (always)
			plhs[cam] = pArray[cam];


			/*************************************************************************/
			/* if required, convert image data to RGB and return it to MATLAB...	 */
			/*************************************************************************/
			if(retIMG) {
				
				/* create a MATLAB array with 'm_width' columns, 'm_height' rows, 'real numbers'	*/
				pArray2[cam] = mxCreateNumericArray(3, (int const *)&dims[0], mxUINT8_CLASS, mxREAL);
				//mexPrintf("pArray created\n");
	
				/* transfer data from DMA buffer to the MATLAB buffer...		 */
				MATbuf = (unsigned char *)mxGetPr(pArray2[cam]);
				
				// convert YUVY to RGB
				// ?? could possibly avoid this extra step -> use subset of 'bufRGB'  (fw-01-08)
				// ?? could possibly avoid this extra step -> use subset of 'bufRGB'  (fw-01-08)
			// -> /* convert camera data to RGB and copy it to 'bufRGB' (input format automatically honoured) */
			// -> if(theCamera.getRGB(bufRGB, nElements) != CAM_SUCCESS)
			// -> 	mexErrMsgTxt("Error during conversion to RGB.\n");
				// ?? could possibly avoid this extra step -> use subset of 'bufRGB'  (fw-01-08)
				// ?? could possibly avoid this extra step -> use subset of 'bufRGB'  (fw-01-08)
				convYUYV2RGB(img, (yuv422 *)yuyvBuf);
				
		
				/* copy RGB to the MATLAB buffer... & turn image upside down */
				//
				// define the following macro to reverse the orientation of the image (upside down)
				//#define	UPSIDEDOWN
				//
				{
					
					#ifdef UPSIDEDOWN
					unsigned long	lastRGBelement = dims[0]*processFrameNumPix;
					#endif
					
					for(unsigned int row=0; row<dims[0]; row++) /* height */ {
						//mexPrintf("row = %d  --  ", row);
						//for(unsigned int col=0; col<dims[1]; col++) /* width */ {
						for(unsigned int col=0; col<dims[1]; col++) /* width */ {
							//mexPrintf("%d ", col);
							
							#ifdef UPSIDEDOWN
							unsigned int  RGBindex = lastRGBelement - (row+1)*processFrameNumPix + col + packetOffsetX;
							#else
							unsigned int  RGBindex = row*processFrameNumPix + col + packetOffsetX;
							#endif /* UPSIDEDOWN */
							
							MATbuf[row+col*dims[0]+0*dims[1]*dims[0]] = img[RGBindex].red;
							MATbuf[row+col*dims[0]+1*dims[1]*dims[0]] = img[RGBindex].green;
							MATbuf[row+col*dims[0]+2*dims[1]*dims[0]] = img[RGBindex].blue;
							
						}
						
					}
					
				} /* copy RGB */
				
				// set return pointer
				plhs[2+cam] = pArray2[cam];
			
			} /* retIMG */

		}  /* for all cameras */

    } /* initCamera == 1 */
	
} /* mexFunction ============================================================ */

⌨️ 快捷键说明

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