📄 capproc.cpp
字号:
}
/* (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) {
//mexPrintf("Capturing image\n");
if(theCamera.CaptureImage() != CAM_SUCCESS)
mexErrMsgTxt("Error during image capture.\n");
/* ------------- CMVision ------------- */
/* convert current frame to the YUYV format (required by CMVISION) */
convCurrentFrame2YUYV(mode, yuyvBuf);
// process image data -- sets region info in 'vision', does not alter yuyvBuf
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 = 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,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,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,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,i,3,fout);
}
}
}
//mexPrintf("Updated Regions\n");
// free dynamically allocated memory
for(i=0; i<maxCOL; i++) mxFree(retREG[i]);
/*************************************************************************/
/* 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 = 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);
// 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[1] = pArray2;
} /* retIMG */
} /* initCamera == 1 */
// return output array pointer (always)
plhs[0] = pArray;
} /* mexFunction ============================================================ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -