/***********************************************************************
* SIVP - Scilab Image and Video Processing toolbox
* Copyright (C) 2005 Shiqi Yu
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***********************************************************************/
#include "common.h"
/**************************************************
* nRow: the first dim
* nCol: the second dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
* nType: I_CHAR, I_INT16, I_INT32, I_UCHAR, I_UINT16, I_UINT32
**************************************************/
BOOL
Create2DIntMat(int nPos, int nRow, int nCol, void * pData, int nType)
{
SciIntMat IntMat;
//create SciIntMat for the image data
IntMat.m = nRow;
IntMat.n = nCol;
IntMat.l = -1; /* dimensions matrix not in scilab stack */
IntMat.it = nType;
IntMat.D = pData;
CreateVarFromPtr(nPos,"I",&(IntMat.m), &(IntMat.n), &IntMat );
return TRUE;
}
/**************************************************
* Create a 2D nRow * nCol float matrix(single precision, 4bytes)
* nRow: the first dim
* nCol: the second dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
**************************************************/
BOOL
Create2DFloatMat(int nPos, int nRow, int nCol, float * pData)
{
CreateVarFromPtr(nPos,"r",&nRow, &nCol, &pData);
return TRUE;
}
/**************************************************
* Create a 2D nRow * nCol double matrix(double precision, 8bytes)
* nRow: the first dim
* nCol: the second dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
**************************************************/
BOOL
Create2DDoubleMat(int nPos, int nRow, int nCol, double * pData)
{
CreateVarFromPtr(nPos,"d",&nRow, &nCol, &pData);
return TRUE;
}
/**************************************************
* Create a 3D nRow * nCol * nCh integer matrix
* nRow: the first dim
* nCol: the second dim
* nCh: the third dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
* nType: I_CHAR, I_INT16, I_INT32, I_UCHAR, I_UINT16, I_UINT32
**************************************************/
BOOL
Create3DIntMat(int nPos, int nRow, int nCol, int nCh, void* pData, int nType)
{
static char *Str[]= { "hm","dims","entries"};
int m1=1,n1=3;
int mL=3,nL=1,lL, un=1;
SciIntMat Dims;
SciIntMat IntData;
//create SciIntMat for dimentional information
Dims.m = 1;
Dims.n = 3;
Dims.l = -1; /* dimensions matrix not in scilab stack */
Dims.it = I_INT32;
Dims.D = malloc(Dims.n * sizeof(int)); //dim data
if (!Dims.D)
{
Scierror(999,"Unable to alloc memory for the image\n");
return FALSE;
}
IC_INT32(Dims.D)[0] = nRow;
IC_INT32(Dims.D)[1] = nCol;
IC_INT32(Dims.D)[2] = nCh;
//create SciIntMat for the image data
IntData.m = nRow ;
IntData.n = nCol * nCh;
IntData.l = -1; /* dimensions matrix not in scilab stack */
IntData.it = nType;
IntData.D = pData;
CreateVar(nPos,"m", &mL, &nL, &lL);
CreateListVarFromPtr(nPos,1,"S", &m1, &n1, Str);
CreateListVarFromPtr(nPos,2,"I",&(Dims.m), &(Dims.n), &Dims);
CreateListVarFromPtr(nPos,3,"I",&(IntData.m), &(IntData.n), &IntData );
/* free memory */
free(Dims.D);
return TRUE;
}
/**************************************************
* Create a 3D nRow * nCol * nCh float matrix (single precision, 4 bytes)
* nRow: the first dim
* nCol: the second dim
* nCh: the third dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
**************************************************/
BOOL
Create3DFloatMat(int nPos, int nRow, int nCol, int nCh, float* pData)
{
static char *Str[]= { "hm","dims","entries"};
int m1=1,n1=3;
int mL=3,nL=1,lL;
int un=1;
int nSize = nRow * nCol * nCh;
SciIntMat Dims;
//create SciIntMat for dimentional information
Dims.m = 1;
Dims.n = 3;
Dims.l = -1; /* dimensions matrix not in scilab stack */
Dims.it = I_INT32;
Dims.D = malloc(Dims.n * sizeof(int)); //dim data
if (!Dims.D)
{
Scierror(999,"Unable to alloc memory for the image\n");
return FALSE;
}
IC_INT32(Dims.D)[0] = nRow;
IC_INT32(Dims.D)[1] = nCol;
IC_INT32(Dims.D)[2] = nCh;
CreateVar(nPos,"m", &mL, &nL, &lL);
CreateListVarFromPtr(nPos,1,"S", &m1, &n1, Str);
CreateListVarFromPtr(nPos,2,"I",&(Dims.m), &(Dims.n), &Dims);
CreateListVarFromPtr(nPos,3,"r", &nSize, &un, &pData );
/* free memory */
free(Dims.D);
return TRUE;
}
/**************************************************
* Create a 3D nRow * nCol * nCh double matrix (double precision, 8 bytes)
* nRow: the first dim
* nCol: the second dim
* nCh: the third dim
* pData: pData is the data for matrix, and it can be freed after this function is called.
**************************************************/
BOOL
Create3DDoubleMat(int nPos, int nRow, int nCol, int nCh, double* pData)
{
static char *Str[]= { "hm","dims","entries"};
int m1=1,n1=3;
int mL=3,nL=1,lL;
int un=1;
int nSize = nRow * nCol * nCh;
SciIntMat Dims;
//create SciIntMat for dimentional information
Dims.m = 1;
Dims.n = 3;
Dims.l = -1; /* dimensions matrix not in scilab stack */
Dims.it = I_INT32;
Dims.D = malloc(Dims.n * sizeof(int)); //dim data
if (!Dims.D)
{
Scierror(999,"Unable to alloc memory for the image\n");
return FALSE;
}
IC_INT32(Dims.D)[0] = nRow;
IC_INT32(Dims.D)[1] = nCol;
IC_INT32(Dims.D)[2] = nCh;
CreateVar(nPos,"m", &mL, &nL, &lL);
CreateListVarFromPtr(nPos,1,"S", &m1, &n1, Str);
CreateListVarFromPtr(nPos,2,"I",&(Dims.m), &(Dims.n), &Dims);
CreateListVarFromPtr(nPos,3,"d", &nSize, &un, &pData );
/* free memory */
free(Dims.D);
return TRUE;
}
/************************************************************
* convert IplImage to SCI matrix
************************************************************/
BOOL IplImg2Mat(IplImage * pImage, int nPos)
{
void * pMatData;
int nBytes;
int nType;
if(pImage == NULL)
return FALSE;
//if bottom-left origin
if(pImage->origin==1)
{
cvFlip(pImage, NULL, 0);
pImage->origin=0;
}
/*how many bytes per pixel per channel*/
nBytes = pImage->depth;
if (nBytes > IPL_DEPTH_SIGN)
nBytes -= IPL_DEPTH_SIGN;
nBytes = nBytes >> 3;
/*alloc memory for matrix data*/
pMatData = malloc(pImage->width * pImage->height * pImage->nChannels * nBytes);
if(pMatData == NULL)
return FALSE;
ImgData2MatData(pImage, pMatData);
/*convert IplImage data type to scilab data type*/
nType = IplType2SciType(pImage->depth);
if (nType <= 0)
{
free(pMatData);
return FALSE;
}
/*create matrix for scilab*/
if(pImage->nChannels == 1)
{
switch(nType){
case I_CHAR:
case I_UCHAR:
case I_INT16:
case I_UINT16:
case I_INT32:
Create2DIntMat(nPos, pImage->height, pImage->width, pMatData, nType);
break;
case SIVP_FLOAT:
Create2DFloatMat(nPos,pImage->height, pImage->width, pMatData);
break;
case SIVP_DOUBLE:
Create2DDoubleMat(nPos,pImage->height, pImage->width, pMatData);
break;
}
}
else
{
switch(nType){
case I_CHAR:
case I_UCHAR:
case I_INT16:
case I_UINT16:
case I_INT32:
Create3DIntMat(nPos, pImage->height, pImage->width, pImage->nChannels, pMatData, nType);
break;
case SIVP_FLOAT:
Create3DFloatMat(nPos,pImage->height, pImage->width, pImage->nChannels, pMatData);
break;
case SIVP_DOUBLE:
Create3DDoubleMat(nPos,pImage->height, pImage->width, pImage->nChannels, pMatData);
break;
}
}
/*free matrix data*/
free(pMatData);
return TRUE;
}
/************************************************************
* get image dimension information and the data address
* input: nPos(the nPos'th argument, the argument shouble be a mlist)
*
************************************************************/
IplImage * CreateIplImgFromHm(int nPos)
{
char ** pStr;
int * pListHeader;
int * pDataHeader;
void * pData;
int m, n, l;
int m1, n1, m2, n2, m3, n3, l3;
SciIntMat Dims;
SciIntMat IntMat;
int nWidth, nHeight, nCh=1;
int iplType;
IplImage * pImg = NULL;
GetListRhsVar(nPos, 1 ,"S",&m1,&n1,&pStr);
/*check whether the the argument is a hypermatrix*/
if( m1 !=1 || n1 !=3)
goto NOT_HM;
if( strcmp(pStr[0], "hm") != 0 || strcmp(pStr[1], "dims") != 0 || strcmp(pStr[2], "entries") != 0)
goto NOT_HM;
/*get the dimension information, it's stored in the second element of the mlist*/
GetListRhsVar(nPos,2,"I", &m2, &n2,&Dims);
if( m2*n2 !=2 && m2*n2 !=3)
goto NOT_HM;
nHeight = IC_INT32(Dims.D)[0];
nWidth = IC_INT32(Dims.D)[1];
if(m2*n2 == 3)
nCh = IC_INT32(Dims.D)[2];
else
nCh = 1;
/*get mlist data structure*/
pListHeader = (int*)GetData(nPos);
/*data is stored in the third element*/
/*data struct is get first*/
pDataHeader = (int*)( ((char*)pListHeader) + 24 + (pListHeader[4]-1)*8 );
/*the next step is to get the data type and the data*/
/*the data type is store in the first 4 bytes as a integer*/
switch( pDataHeader[0] ){
case 1: /*if the data is real*/
iplType = IPL_DEPTH_64F;
GetListRhsVar(nPos, 3, "d", &m3, &n3, &l3);
pData = stk(l3);
break;
case 8: /*integer*/
GetListRhsVar(nPos, 3, "I", &m3, &n3, &IntMat);
m3 = IntMat.m;
n3 = IntMat.n;
iplType = SciType2IplType(IntMat.it);
if(iplType==0)
{
sciprint("This integer data type is not supported by SIVP. Integer type number: %d. \r\n", IntMat.it);
goto EXIT_TAG;
}
pData = IntMat.D;
break;
default:
sciprint("The data type of %d'th argument is %d. It can't be converted to an image.\r\n",nPos, pDataHeader[0] );
goto EXIT_TAG;
}
/*check dimension */
if(m3*n3 != nWidth * nHeight * nCh)
{
sciprint("Broken hypermatrix: The hypermatrix declares %d X %d X %d, but actually %d elements.\r\n", nHeight, nWidth, nCh, m3*n3);
goto EXIT_TAG;
}
/*create a IplImage to receiving the data*/
pImg = cvCreateImage(cvSize(nWidth, nHeight), iplType, nCh);
if(pImg == NULL)
{
sciprint("Create IplImage for %d'th argument failed.\r\n", nPos);
goto EXIT_TAG;
}
/*change data order and copy data*/
MatData2ImgData(pImg, pData );
FreeRhsSVar(pStr);
return pImg;
NOT_HM:
sciprint("The %d'th argument is not a hypermatrix.\r\n", nPos);
FreeRhsSVar(pStr);
return NULL;
EXIT_TAG:
FreeRhsSVar(pStr);
return NULL;
}
/************************************************************
* convert IplImage to SCI matrix
************************************************************/
IplImage * Mat2IplImg(int nPos)
{
IplImage * pImg;
int mR1, nR1, lR1;
SciIntMat IntMat;
int iplType;
switch(VarType(nPos)){
case 1: /*real or complex constant matrix.*/
GetRhsVar(nPos, "d", &mR1, &nR1, &lR1);
pImg = cvCreateImage(cvSize(nR1, mR1), IPL_DEPTH_64F, 1);
/*if can not create the IplImage*/
if(pImg == NULL)
{
sciprint("Create IplImage for %d'th argument failed.\r\n", nPos);
return NULL;
}
MatData2ImgData(pImg, stk(lR1) );
return pImg;
break;
/*integer matrix*/
case 8:
GetRhsVar(nPos, "I", &mR1, &nR1, &IntMat);
iplType = SciType2IplType(IntMat.it);
if(iplType==0)
{
sciprint("This integer data type is not supported by SIVP. Integer type number: %d. \r\n", IntMat.it);
return NULL;
}
pImg = cvCreateImage(cvSize(nR1, mR1),iplType , 1);
if(pImg == NULL)
{
sciprint("Create IplImage for %d'th argument failed.\r\n", nPos);
return NULL;
}
MatData2ImgData(pImg, IntMat.D );
return pImg;
break;
case 17:
return CreateIplImgFromHm( nPos);
break;
default:
sciprint("This data type can't be converted to an image.\r\n");
return NULL;
}
}
/************************************************************
* change the data order from column-wise to row-wise
************************************************************/
BOOL MatData2ImgData(IplImage * pImage, void * pMatData)
{
// IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
//IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F
int row, col, ch;
long nCount = 0;
int nBytes;
char * pDst = NULL;
char * pSrc = NULL;
if (pImage == NULL || pMatData == NULL)
return FALSE;
pDst = (char*)(pImage->imageData);
pSrc = (char*)pMatData;
/*how many bytes per pixel per channel*/
nBytes = pImage->depth;
if (nBytes > IPL_DEPTH_SIGN)
nBytes -= IPL_DEPTH_SIGN;
nBytes = nBytes >> 3;
for(ch = 0; ch < pImage->nChannels ; ch++) //the order of IplImage is BGR
for(col =0; col < pImage->width; col++)
for(row = 0; row < pImage->height; row++)
{
memcpy(pDst + pImage->widthStep*row + (col*pImage->nChannels + (pImage->nChannels-ch-1))*nBytes, pSrc+nCount, nBytes );
nCount += nBytes;
}
return TRUE;
}
/************************************************************
* change the data order from row-wise to column-wise
************************************************************/
BOOL ImgData2MatData(IplImage * pImage, void * pMatData)
{
// IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
//IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F
int row, col, ch;
long nCount = 0;
int nBytes;
char * pSrc = NULL;
char * pDst = NULL;
if (pImage == NULL || pMatData == NULL)
return FALSE;
pSrc = (char*)(pImage->imageData);
pDst = (char*)pMatData;
/*how many bytes per pixel per channel*/
nBytes = pImage->depth;
if (nBytes > IPL_DEPTH_SIGN)
nBytes -= IPL_DEPTH_SIGN;
nBytes = nBytes >> 3;
for(ch = 0; ch < pImage->nChannels ; ch++) //the order of IplImage is BGR
for(col =0; col < pImage->width; col++)
for(row = 0; row < pImage->height; row++)
{
memcpy(pDst+nCount, pSrc + pImage->widthStep*row + (col*pImage->nChannels + (pImage->nChannels-ch-1))*nBytes, nBytes );
nCount += nBytes;
}
return TRUE;
}
/************************************************************
* unsigned int32 is not supported (no this type in OpenCV)
************************************************************/
int IplType2SciType(int IplType)
{
switch(IplType) {
case IPL_DEPTH_8U: return I_UCHAR;
case IPL_DEPTH_8S: return I_CHAR;
case IPL_DEPTH_16U: return I_UINT16;
case IPL_DEPTH_16S: return I_INT16;
case IPL_DEPTH_32S: return I_INT32;
case IPL_DEPTH_32F: return SIVP_FLOAT;
case IPL_DEPTH_64F: return SIVP_DOUBLE;
default: return 0;
}
}
/************************************************************
* unsigned int32 is not supported (no this type in OpenCV)
************************************************************/
int SciType2IplType(int SciType)
{
switch(SciType) {
case I_UCHAR: return IPL_DEPTH_8U;
case I_CHAR: return IPL_DEPTH_8S;
case I_UINT16: return IPL_DEPTH_16U;
case I_INT16: return IPL_DEPTH_16S;
case I_INT32: return IPL_DEPTH_32S;
case SIVP_FLOAT: return IPL_DEPTH_32F;
case SIVP_DOUBLE: return IPL_DEPTH_64F;
default: return 0;
}
}
/* convert data from row-wise to columnwise */
void img2mat(unsigned char* pSrc, unsigned char * pDst, int nWidth, int nHeight, int nCh)
{
int row, col, ch;
long nCount = 0;
for(ch =0; ch < nCh; ch++)
for(col =0; col < nWidth; col++)
for(row = 0; row < nHeight; row++)
{
*(pDst+nCount) = *(pSrc+(nWidth*nCh)*row+col*nCh+ch);
nCount++;
}
}
/* convert data from columnwise to row-wise */
void mat2img(unsigned char * pMat, unsigned char *pImg, int nWidth, int nHeight, int nCh)
{
int row, col, ch;
long offset;
long nCount = 0;
for(row=0; row < nHeight; row++)
for(col=0; col < nWidth; col++)
for (ch=0; ch < nCh; ch++)
{
offset = ch*(nWidth*nHeight) + col * nHeight + row;
pImg[nCount] = pMat[offset];
nCount++;
}
}
syntax highlighted by Code2HTML, v. 0.9.1