///////////////////////////////////////////////////////////////////////////// // Name: crvmisc.cpp // Purpose: // Author: Cesar Mauri Loba (cesar at crea-si dot com) // Modified by: // Created: 23/05/2008 // Copyright: (C) 2008 Cesar Mauri Loba - CREA Software Systems // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . ///////////////////////////////////////////////////////////////////////////// #include "crvmisc.h" #include #include #include // uintptr_t type #if defined(WIN32) #include #else #include #endif // Dona l'adre�a de mem�ria del p�xel a la posici� X, Y (DEPRECAT) char *crvImgByteOffset (const IplImage *img, int x, int y) { assert (img->nChannels== 1); switch (img->depth) { case IPL_DEPTH_8U: return (char *)((uintptr_t) img->imageData + x + (y * img->widthStep)); case IPL_DEPTH_16U: return (char *)((uintptr_t) img->imageData + x * 2 + (y * img->widthStep)); default: assert (0); } return NULL; // Evitar Warning } // Dona l'adre�a de mem�ria del p�xel a la posici� X, Y void *crvImgOffset (const IplImage *img, int x, int y) { switch (img->depth) { case IPL_DEPTH_8U: case IPL_DEPTH_8S: return (void *)((uintptr_t) img->imageData + x * img->nChannels + (y * img->widthStep)); case IPL_DEPTH_16U: case IPL_DEPTH_16S: return (void *)((uintptr_t) img->imageData + x * 2 + (y * img->widthStep)); case IPL_DEPTH_32S: case IPL_DEPTH_32F: return (void *)((uintptr_t) img->imageData + x * 4 + (y * img->widthStep)); default: assert (0); } return NULL; // Evitar Warning } // Calcula limits en X, Y segons el ROI d'una imatge void crvGetROILimits (const IplImage *img, int &xIni, int &yIni, int &xLim, int &yLim) { if (img->roi== NULL) { // No s'ha indicat regi� d'inter�s -> tota la imatge xIni= 0; yIni= 0; xLim= img->width; yLim= img->height; } else { // S'ha indicat regi� d'inter�s xIni= img->roi->xOffset; yIni= img->roi->yOffset; xLim= xIni + img->roi->width; yLim= yIni + img->roi->height; // Trunca dins els l�mits reals de la imatge if (xIni< 0) xIni= 0; if (yIni< 0) yIni= 0; if (xLim> img->width) xLim= img->width; if (yLim> img->height) yLim= img->height; //assert (xLim<= img->width && yLim<= img->height); } } // Dona la intersecci� entre les ROI de 2 imatges void crvGetROIIntersectionLimits (IplImage *img1, IplImage *img2, int &xIni1, int &yIni1, int &xLim1, int &yLim1, int &xIni2, int &yIni2, int &xLim2, int &yLim2) { int width, height; if (img1->roi== NULL) { xIni1= 0; yIni1= 0; width= img1->width; height= img1->height; } else { xIni1= img1->roi->xOffset; yIni1= img1->roi->yOffset; width= img1->roi->width; height= img1->roi->height; } if (img2->roi== NULL) { xIni2= 0; yIni2= 0; width= (width< img2->width ? width : img2->width); height= (height< img2->height ? height : img2->height); } else { xIni2= img2->roi->xOffset; yIni2= img2->roi->yOffset; width= (width< img2->roi->width ? width : img2->roi->width); height= (height< img2->roi->height ? height : img2->roi->height); } // Limits xLim1= xIni1 + width; yLim1= yIni1 + height; xLim2= xIni2 + width; yLim2= yIni2 + height; } // Pinta en ASCII una imatge binaria /* void crvAsciiPaint (IplImage *img, unsigned short thres) { int x, y; unsigned short pix; for (y= 0; y< img->height; y++) { for (x= 0; x< img->width; x++) { pix= 0; iplGetPixel (img, x, y, &pix); printf ("%c", (pix< thres ? '.' : '#')); } printf ("\n"); } }*/ // Copia una ROI d'una imatge sobre una nova imatge aplicant // l'escalat que s'indica per par�metre. La ROI de la imatge // dest� ha de ser suficientment gran com per encabir // la ROI origen un cop escalada. /* void crvCopyScaleImage (IplImage *src, IplImage *dst, float scale) { int xDst, xSrc, yDst, ySrc; assert (src && dst && scale> 0.0f); //assert (src->roi!= NULL && dst->roi!= NULL); // Redimensiona imatge if (scale== 1.0) { xSrc= ySrc= xDst= yDst= 1; } else { xSrc= 10000; ySrc= xSrc; xDst= (int) ((float) xSrc * scale); yDst= xDst; } iplResize(src, dst, xDst, xSrc, yDst, ySrc, IPL_INTER_CUBIC); }*/ // Semi-binaritza una imatge de manera que per sobre o per sota // del llindar indicat no es modifiquen els valors dels p�xels /* void crvSemiBinarize (IplImage *img, unsigned char thres, unsigned char fillVal, bool fillLower) { int xIni, yIni, xLim, yLim, x, y; unsigned char *pBuff, min= 255; assert (img->depth== IPL_DEPTH_8U); crvGetROILimits (img, xIni, yIni, xLim, yLim); if (fillLower) { for (y= yIni; y< yLim; y++) { pBuff= (unsigned char *) crvImgByteOffset (img, xIni, y); for (x= xIni; x< xLim; x++) { if (*pBuff< thres) *pBuff= fillVal; pBuff++; } } } else { for (y= yIni; y< yLim; y++) { pBuff= (unsigned char *) crvImgByteOffset (img, xIni, y); for (x= xIni; x< xLim; x++) { if (*pBuff>= thres) *pBuff= fillVal; //else *pBuff= MapRange (0, thres, 0, 40, *pBuff); //if (*pBuff< 255 && *pBuff> 35) *pBuff= 35; pBuff++; } } } } */ // Calcula la diferencia de 2 imatges en valor absolut void crvAbsSubstract (IplImage *srcA, IplImage *srcB, IplImage *dst) { int x, y, xIni, yIni, xLim, yLim; unsigned char *pBuffA, *pBuffB, *pBuffRes; assert (srcA->depth== IPL_DEPTH_8U && srcB->depth== IPL_DEPTH_8U && dst->depth== IPL_DEPTH_8U); assert (srcA->width== srcB->width && srcA->width== dst->width && srcA->height== srcB->height && srcA->height== dst->height); assert (!srcA->roi && !srcB->roi && !dst->roi); pBuffA= (unsigned char *) srcA->imageData; pBuffB= (unsigned char *) srcB->imageData; pBuffRes= (unsigned char *) dst->imageData; crvGetROILimits (srcA, xIni, yIni, xLim, yLim); for (y= yIni; y< yLim; y++) { pBuffA= (unsigned char *) crvImgByteOffset (srcA, xIni, y); pBuffB= (unsigned char *) crvImgByteOffset (srcB, xIni, y); pBuffRes= (unsigned char *) crvImgByteOffset (dst, xIni, y); for (x= xIni; x< xLim; x++) { *pBuffRes = (unsigned char) abs ((int) *pBuffA - (int) *pBuffB); pBuffA++; pBuffB++; pBuffRes++; } } } void crvConvert16BinToRGBA (IplImage *pSrcImg, IplImage *pDstImg) { int i; unsigned short *pWordSrc; unsigned char *pByteDst; assert (pSrcImg && pDstImg); pWordSrc= (unsigned short *) pSrcImg->imageData; pByteDst= (unsigned char *) pDstImg->imageData; int bytesPerPixel= pDstImg->depth / 8; if (bytesPerPixel== 4) { for (i= 0; i< pDstImg->imageSize; i+= 4) { if (*pWordSrc) { *pByteDst++= 255; *pByteDst++= 255; *pByteDst++= 255; pByteDst++; } else { *pByteDst++= 0; *pByteDst++= 0; *pByteDst++= 0; pByteDst++; } pWordSrc++; } } else { for (i= 0; i< pDstImg->imageSize; i+= 3) { if (*pWordSrc) { *pByteDst++= 255; *pByteDst++= 255; *pByteDst++= 255; } else { *pByteDst++= 0; *pByteDst++= 0; *pByteDst++= 0; } pWordSrc++; } } } // Ajusta un rectangle per que quedi dins uns limits establerts // Retorna true si s'ha modificat el rectangle // mode: bool crvFitRect (CvRect *rect, int width, int height) { bool modif= false; assert (rect->x<= width); assert (rect->y<= height); if (rect->x < 0) { rect->width+= rect->x; rect->x= 0; assert (rect->width> 0); modif= true; } if (rect->x + rect->width> width) { rect->width= width - rect->x; modif= true; } if (rect->y < 0) { rect->height+= rect->y; rect->y= 0; assert (rect->height> 0); modif= true; } if (rect->y + rect->height> height) { rect->height= height - rect->y; modif= true; } assert ((rect->x + width)>= rect->width); assert ((rect->y + height)>= rect->height); return (modif); } bool crvFitROI (IplImage *img, IplROI *roi) { CvRect rect; bool retval; rect.x= roi->xOffset; rect.y= roi->yOffset; rect.width= roi->width; rect.height= roi->height; retval= crvFitRect (&rect, img->width, img->height); roi->xOffset= rect.x; roi->yOffset= rect.y; roi->width= rect.width; roi->height= rect.height; return retval; } // Converteix una imatge void crvConvert32FPToGray (IplImage *pSrcImg, IplImage *pDstImg, float min, float max) { float *pOrig, factor; unsigned char *pDst; int x, y, xIni, yIni, xLim, yLim; assert (pSrcImg->depth== IPL_DEPTH_32F); assert (pDstImg->depth== IPL_DEPTH_8U); assert (pSrcImg->width== pDstImg->width && pSrcImg->height== pDstImg->height); factor= 255.0f / (float)(max - min); crvGetROILimits (pSrcImg, xIni, yIni, xLim, yLim); for (y= yIni; y< yLim; y++) { pOrig= (float *) crvImgOffset (pSrcImg, xIni, y); pDst= (unsigned char *) crvImgOffset (pDstImg, xIni, y); for (x= xIni; x< xLim; x++) { *pDst= (unsigned char) ((*pOrig - min) * factor); pOrig++; pDst++; } } } void crvThresholdFP (IplImage *pSrcImg, IplImage *pDstImg, float threshold, float zero) { int y, x, xIni, yIni, xLim, yLim; float *pSrc, *pDst; assert (pSrcImg && pDstImg); assert (pSrcImg->depth== IPL_DEPTH_32F && pDstImg->depth== IPL_DEPTH_32F); assert (pSrcImg->width== pDstImg->width && pSrcImg->height== pDstImg->height); crvGetROILimits (pSrcImg, xIni, yIni, xLim, yLim); for (y= yIni; y< yLim; y++) { pSrc= (float *) crvImgOffset (pSrcImg, xIni, y); pDst= (float *) crvImgOffset (pDstImg, xIni, y); for (x= xIni; x< xLim; x++) { if (*pSrc>= threshold) { *pDst= *pSrc; } else { *pDst= zero; } pSrc++; pDst++; } } } // Calcula el m�dul del gradient d'una imatge // Veure: iplConvolve2D /* void crvGradientModulus (IplImage *pSrcImg, IplImage *pDstImg) { cvSobel (pSrcImg, pDstImg, 1, 1); int nShiftR; IplConvKernel *kernels[2]; kernels[0]= iplCreateConvKernel(3, 3, 1, 1, { -1, 0, 1, -2, 0, 2, -1, 0, 1 }, &nShiftR); assert (kernels[0]); kernels[1]= iplCreateConvKernel(3, 3, 1, 1, { 1, 2, 1, 0, 0, 0, -1, -2, -1 }, &nShiftR); assert (kernels[1]); iplConvolve2D(pSrcImage, pDstImage, &kernels, 2, IPL_SUMSQROOT); DeleteConvKernel (kernels[0]); DeleteConvKernel (kernels[1]); } */ /* void crvGradientModulus (IplImage *pSrcImg, IplImage *pDstImg, IplImage *pTmpImg1, int *maxX, int *maxY) { int retval; unsigned char *pVVal, *pHVal, *pDst, max= 0; int x, y, xIni, yIni, xLim, yLim; retval= iplFixedFilter (pSrcImg, pDstImg, IPL_SOBEL_3x3_V); assert (retval== 0); retval= iplFixedFilter (pSrcImg, pTmpImg1, IPL_SOBEL_3x3_H); assert (retval== 0); crvGetROILimits (pSrcImg, xIni, yIni, xLim, yLim); *maxX= 0; *maxY= 0; for (y= yIni; y< yLim; y++) { pVVal= (unsigned char *) crvImgOffset (pDstImg, xIni, y); pHVal= (unsigned char *) crvImgOffset (pTmpImg1, xIni, y); pDst= (unsigned char *) crvImgOffset (pDstImg, xIni, y); for (x= xIni; x< xLim; x++) { *pDst= (unsigned char) (((int) *pVVal + (int) *pHVal) / 2); if (*pDst> max) { max= *pDst; *maxX= x; *maxY= y; } //val= ((int) *pVVal) * ((int) *pVVal) + ((int) *pHVal) * ((int) *pHVal); //val= (int) (sqrt (val) / 362.1f); // *pDst= val; pVVal++; pHVal++; pDst++; } } } */