📄 comlib.cpp
字号:
CString PathName = in.PathName;
CString srcFile = PathName + in.SrcFile;
CString desFile = PathName + in.DesFile;
BYTE ** src = InputImageWithName(&sRow, &sCol , srcFile);
if( src == NULL ) return false ;
if(dRow <=0 || dCol<=0 )
{
dRow = sRow;
dCol = sCol;
}
BYTE ** des = (BYTE**) fspace_2d( dRow, dCol, sizeof(BYTE));
if( HalfSize > 0)
{
BYTE ** midimg = PreProcess(src, sRow , sCol, HalfSize);
ImgScale( midimg , sRow , sCol , des , dRow, dCol );
ffree_2d( (void**) midimg , sRow);
}
else
ImgScale( src , sRow , sCol , des , dRow, dCol );
OutputImageWithName(des , dRow, dCol , desFile );
ffree_2d( (void**) des , dRow);
ffree_2d( (void**) src , sRow);
return ret;
}
// 用插值放大后再作尺度和旋转变形处理
BYTE ** CComlib::DigDistortSubImgFine(BYTE ** src , int sRow, int sCol, int dRow, int dCol, float cR , float cC , float scale , float theta)
{
ASSERT( scale >0.0 );
// Rotate matrix
float a11, a12, a21, a22;
// inverse trans matric
a11 = cos(theta);
a12 = sin(theta);
a21 = -sin(theta);
a22 = cos(theta);
// the center point in dest subimage of (cC , cR) in original big image
int cy = dRow/2;
int cx = dCol/2;
BYTE ** des = (BYTE**) fspace_2d( dRow, dCol, sizeof(BYTE));
// 如果没有变形,则从原图中直接截取子图
if(scale==1 && theta ==0)
{
for( int i=0 ; i<dRow; i++)
for( int j=0 ; j<dCol; j++)
{
int m = i - cy + cR ;
int n = j - cx + cC ;
des[i][j] = src[m][n];
}
return des;
}
// 否则,进行变形处理,再截取子图
// 对于尺度变化因子大于1的情况,可以按下面直接作变形处理。
// 而对于尺度变化因子小于1的情况,可以按一定倍数的尺度变形因子来处理后,再缩小一定倍数。
// 对于变形模拟中,没有考虑用变形因子的方法来处理,而是等价于不同高度模拟。
// 图象以某点为中心进行放缩与旋转变换,并对应截取某尺寸大小的子图,中心点对应子图的中心点。
// 步骤:
// STEP1 : 利用3次线性插值原始图象src放大4倍×Scale,
// STEP2 : 然后对放大图象旋转角度Theta
// STEP3 : 最后将图象变回到子图大小
int dcx0 = dCol / 2; // center cord
int dcy0 = dRow / 2;
float rad = sqrt(dcx0*dcx0+dcy0*dcy0);
float alpha0 = atan( dRow /(float) dCol );
float alphaY = alpha0 + theta;
float alphaX = alpha0 - theta;
int sr1 = int (2*rad*sin(alphaY) + 0.5);
int sc1 = int (2*rad*cos(alphaX) + 0.5);
int sx1 = sc1/2;
int sy1 = sr1/2;
// 从原图中直接截取子图
BYTE ** src1 = (BYTE**) fspace_2d( sr1, sc1, sizeof(BYTE));
for( int i=0 ; i<sr1; i++)
for( int j=0 ; j<sc1; j++)
{
int m = i - sy1 + cR ;
int n = j - sx1 + cC ;
src1[i][j] = src[m][n];
}
int kk = 2;
int sr2 = sr1 * kk * scale +0.5;
int sc2 = sc1 * kk * scale +0.5;
int sx2 = sc2/2;
int sy2 = sr2/2;
int dr2 = dRow * kk * scale + 0.5;
int dc2 = dCol * kk * scale + 0.5;
int dx2 = dc2/2;
int dy2 = dr2/2;
// scale image to big
BYTE ** src2 = ImgScaleCubicLinear( src1, sr1 , sc1 , sr2 , sc2 );
// OutputImageWithName(src2, sr2,sc2,"d:\\bigSrcRot.pic");
// rotate from here with big image
BYTE ** des2 = (BYTE**) fspace_2d( dr2 , dc2,sizeof(BYTE));
for( i=0 ; i<dr2; i++)
for( int j=0 ; j<dc2; j++)
{
// rotate
float x = (a11*(j - dx2) + a12*(i - dy2)) + sx2 ;
float y = (a21*(j - dx2) + a22*(i - dy2)) + sy2 ;
if( x>=0 && x<sx2-1 && y>=0 && y< sy2-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float S = y-m;
float R = x-n;
des2[i][j] = (BYTE)((1-R)*(1-S)*src2[m][n] +
R*(1-S)*src2[m][n+1] + (1-R)*S*src2[m+1][n] +
R*S*src2[m+1][n+1]);
}
else if(x == sx2-1 && y>=0 && y< sy2-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float S = y-m;
des2[i][j] = (BYTE)((1-S)*src2[m][n] + S*src2[m+1][n]) ;
}
else if(y == sy2-1 && x>=0 && x< sx2-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float R = x-n;
des2[i][j] = (BYTE)((1-R)*src2[m][n] + R*src2[m][n+1]);
}
else if(y == sy2-1 && x==sx2-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
des2[i][j] =src2[m][n] ;
}
else
des2[i][j] = 0;
/*
if( x>=0 && x<sc2-1 && y>=0 && y<sr2-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float S = y-m;
float R = x-n;
des2[i][j] = (BYTE)((1-R)*(1-S)*src2[m][n] +
R*(1-S)*src2[m][n+1] + (1-R)*S*src2[m+1][n] +
R*S*src2[m+1][n+1]);
}
else
des2[i][j] = 0;
*/ }
ImgScale( des2 , dr2, dc2, des , dRow, dCol , 2);
ffree_2d((void **) src1 , sr1);
ffree_2d((void **) src2 , sr2);
ffree_2d((void **) des2 , dr2);
return des ;
}
// 直接用变换矩阵计算尺度和旋转变形
BYTE ** CComlib::DigDistortSubImgFast(BYTE ** src , int sRow, int sCol, int dRow, int dCol, float cR , float cC , float scale , float theta)
{
ASSERT( scale >0.0 );
// Rotate matrix
float a11, a12, a21, a22;
// inverse trans matric
a11 = cos(theta);
a12 = sin(theta);
a21 = -sin(theta);
a22 = cos(theta);
// the center point in dest subimage of (cC , cR) in original big image
int cy = dRow/2;
int cx = dCol/2;
BYTE ** des = (BYTE**) fspace_2d( dRow, dCol, sizeof(BYTE));
// 如果没有变形,则从原图中直接截取子图
if(scale==1 && theta ==0)
{
for( int i=0 ; i<dRow; i++)
for( int j=0 ; j<dCol; j++)
{
int m = i - cy + cR ;
int n = j - cx + cC ;
des[i][j] = src[m][n];
}
return des;
}
// 否则,进行变形处理
// 直接作变形处理。
for( int i=0 ; i<dRow; i++)
for( int j=0 ; j<dCol; j++)
{
// rotate
float x = (a11*(j - cx) + a12*(i - cy)) + cC ;
float y = (a21*(j - cx) + a22*(i - cy)) + cR ;
if( x>=0 && x<sCol-1 && y>=0 && y< sRow-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float S = y-m;
float R = x-n;
des[i][j] = (BYTE)((1-R)*(1-S)*src[m][n] +
R*(1-S)*src[m][n+1] + (1-R)*S*src[m+1][n] +
R*S*src[m+1][n+1]);
}
else if(x == sCol-1 && y>=0 && y< sRow-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float S = y-m;
des[i][j] = (BYTE)((1-S)*src[m][n] + S*src[m+1][n]) ;
}
else if(y == sRow-1 && x>=0 && x< sCol-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
float R = x-n;
des[i][j] = (BYTE)((1-R)*src[m][n] + R*src[m][n+1]);
}
else if(y == sRow-1 && x==sCol-1 )
{
int m = (int) floor(y);
int n = (int) floor(x);
des[i][j] =src[m][n] ;
}
else
des[i][j] = 0;
}
return des ;
}
// 用K_L变换对图象序列滤波
void CComlib::ImageFilterByK_L(CString InFileName , int n)
{
/*
CString FileName = InFileName;
int L = FileName.Find('.');
int beginNo = 0;
if( L != -1)
{
FileName = FileName.Left(L) ;
CString tmp = FileName.Right(3) ;
tmp = tmp.SpanIncluding( "0123456789" );
if(tmp.IsEmpty() || tmp.GetLength() !=3 )
{
beginNo = 0;
}
else
{
beginNo = atoi((LPCTSTR )tmp);
FileName = FileName.Left(L-3) ;
}
}
int row, col;
CString tmp;
tmp.Format("%03d.pic",beginNo);
double * dA = InputImageWithName_d( &row, &col, FileName+ tmp);
if(dA == NULL) return ;
delete dA;
int Length = row*col;
int Number = n;
double *X = new double[Length*Number];
double *M = new double[Length];
double *Ramd = new double[Number];
double *VC = new double[Number*Length];
for(int k = 0; k<Number;k++)
{
CString now;
now.Format("%03d.pic",k+beginNo);
CString nowfile = FileName + now;
double * dA = InputImageWithName_d( &row, &col, nowfile);
if(dA == NULL) return ;
for(int m=0;m<Length;m++)
{
X[m*Number + k] = dA[m];
}
delete dA;
}
//K_L变换训练过程,矩阵X(Length*Number),M均值向量(Length),Ramd特征值(Number)
//VC特征向量(列)(Number*Length)
MTrainK_L( X, Length, Number, M, Ramd, VC );
// void MTrainK_L( double ***A, int nX , int nY , int nT , double **XTMap, double **YTMap)
int nX = col;
int nY = row;
int nT = Number;
float **XTMap = (float**) fspace_2d(nT , nX , sizeof(float));
float **YTMap = (float**) fspace_2d(nT , nY , sizeof(float));
for( k = 0; k<Number;k++)
{
CString now;
now.Format("%03d_KL.pic",k+beginNo);
CString OutFile = FileName + now;
float *Y = new float[Length];
for(int m=0;m<Length;m++)
{
Y[m] = (float) Ramd[k]*VC[k*Length+m];
}
int x , y ;
for( x = 0;x<nX;x++)
{
XTMap[k][x] = 0;
for( y = 0;y<nY;y++)
{
XTMap[k][x] += Y[y*nX + x];
}
}
for( y = 0;y<nY;y++)
{
YTMap[k][y] = 0;
for( x = 0;x<nX;x++)
{
YTMap[k][y] += Y[y*nX + x];
}
}
NormalizeToByte( Y , row, col, OutFile );
delete Y;
}
NormalizeToByte( XTMap , nT, nX, FileName + "XT.pic" );
NormalizeToByte( YTMap , nT, nY, FileName+ "YT.pic" );
ffree_2d((void **) YTMap , nT);
ffree_2d((void **) XTMap , nT);
delete X , M , Ramd , VC;
return; */
}
// 图象按行进行K_L变换滤波, 共n帧
void CComlib::ImageFilterByK_LRow(CString InFileName , int nFrame)
{
}
////////////////////////////////
/************************** NORMALIZEFLOAT ***************************/
/* Normalize the float array */
/* Normalize definition is : */
/* Image[i][j] = (Float[i][j]-IMin)/(IMax-IMin)*(Max-Min)+Min */
BYTE** CComlib::NormalizeFloat(float **Float,short YStart,short XStart,
short Row,short Col,short Min,short Max,short Margin)
{
short i,j;
BYTE** NormalizedImage;
float FMax,FMin;
NormalizedImage = (BYTE** )fspace_2d(Row,Col,sizeof(BYTE));
FMax = fMax2d(Float,YStart,XStart,Row,Col,Margin,&FMin);
for(i=Margin;i<Row-Margin;i++)
for(j=Margin;j<Col-Margin;j++)
NormalizedImage[i][j] = (Float[i+YStart][j+XStart]-FMin) / (FMax-FMin) * (Max-Min) + Min;
return NormalizedImage;
}
/****************************** fMax2d ****************************/
/* To get the maximum and the minimum of a 2_dimension float array */
float CComlib::fMax2d(float **a,short YStart,short XStart,short row,short col,short margin,float *minp)
{
register short i,j;
short start_i,end_i,start_j,end_j;
float max,min;
start_i = margin + YStart;
start_j = margin + XStart;
end_i = row - margin + YStart;
end_j = col - margin + XStart;
max = 0;
min = 1024*1024*2+1;
for(i=start_i;i<end_i;i++)
for(j=start_j;j<end_j;j++)
{
if (max<a[i][j])
max = a[i][j];
else if (min>a[i][j])
min = a[i][j];
}
*minp = min;
return max;
}
// 去除边界并从24位图像转换为256色灰度图
// FileName: 文件序列名
// fScale: 转换放大倍数
// x1, x2, y1, y2: 从原始图像中截取子图区域坐标(转换前)
void CComlib::Bmp24To256(CString FileName, CString OutFileName, float fScale, int x1, int x2, int y1, int y2, BOOL bPic)
{
HDIB hDib24 = ::ReadDIBFile( FileName );
if(hDib24 == NULL)
{
AfxMessageBox("NOT bmp file!");
return;
}
int nBits = GetBmpBits(hDib24);
WORD wHeight,wWidth,wNewWidth;
DWORD dwSize;
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDib24);
lpDIBBits=::FindDIBBits(lpDIBHdr);
wHeight=(WORD)(::DIBHeight(lpDIBHdr));
wWidth=(WORD)(::DIBWidth(lpDIBHdr));
wNewWidth=(((wWidth*nBits)+31)/32)*4;
dwSize=(DWORD)wNewWidth*wHeight;
DWORD dwOffset=dwSize;
// 转换为256色灰度图像到数组
unsigned char** uppImage=(unsigned char**)CComlib::fspace_2d(wHeight,wWidth,sizeof(unsigned char));
if(nBits==8)
{
for(int i=0;i<wHeight;i++)
{
dwOffset-= wNewWidth;
for(int j=0;j<wWidth;j++)
uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+j)));
}
}
else if(nBits==24)
{
for(int i=0;i<wHeight;i++)
{
dwOffset-= wNewWidth;
// Y=0.299*R -0.148*G + 0.615*B (RGB)
// Y=0.22R+0.71G+0.07B (PAL D白光)
// Y=0.30R+0.59G+0.11B (NTSC C白光)
for(int j=0;j<wWidth;j++)
{
uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+3*j)));
// uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+3*j))*0.11 + (*(lpDIBBits+dwOffset+3*j+1))*0.59 + (*(lpDIBBits+dwOffset+3*j+2))*0.3 );
// uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+3*j))*0.07 + (*(lpDIBBits+dwOffset+3*j+1))*0.71 + (*(lpDIBBits+dwOffset+3*j+2))*0.22 );
// uppImageG[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+3*j+1)));
// uppImageR[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+3*j+2)));
// if( *(lpDIBBits+dwOffset+3*j) != *(lpDIBBits+dwOffset+3*j+1) )
// TRACE("(%d,%d) --- R(%d) G(%d) B(%d)\n", i, j, *(lpDIBBits+dwOffset+3*j), *(lpDIBBits+dwOffset+3*j+1), *(lpDIBBits+dwOffset+3*j+2));
}
}
}
else if(nBits==16)
{
for(int i=0;i<wHeight;i++)
{
dwOffset-= wNewWidth;
for(int j=0;j<wWidth;j++)
{
uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+2*j)));
}
}
}
unsigned char ** box = uppImage;
int col = wWidth;
int row = wHeight;
BOOL bDig = TRUE;
// 截取图像大小
if(x1 < 0 || y1 < 0 || x1>=x2 || y1>=y2) // 不需截取
{
bDig = FALSE;
}
else
{
if(y2 > wHeight) y2=wHeight;
if(x2 > wWidth) x2=wWidth;
col = x2-x1;
row = y2-y1;
unsigned char ** box1 = ( unsigned char **) fspace_2d( row, col, sizeof(char));
ASSERT(box1 != NULL);
for(int i=y1;i<y2;i++)
for(int j=x1;j<x2;j++)
{
box1[i-y1][j-x1] = uppImage[i][j];
}
ffree_2d((void**)uppImage, wHeight);
box = box1;
}
// 尺度变换
if(fScale != 1 && fScale>0)
{
int desR = fScale*row;
int desC = fScale*col;
BYTE ** out = ImgScaleCubicLinear(box , row, col, desR , desC);
if(bPic)
OutputImageWithName( out , desR ,desC , OutFileName );
else
BOOL bRet = WriteAsBmp( out , desR ,desC , OutFileName );
ffree_2d((void**)out, desR);
}
else
{
if(bPic)
OutputImageWithName( box , row, col, OutFileName );
else
BOOL bRet = WriteAsBmp( box , row, col, OutFileName );
}
ffree_2d((void**)box, row);
::GlobalUnlock((HGLOBAL)hDib24);
if (hDib24 != NULL)
::GlobalFree((HGLOBAL) hDib24);
return ;
}
void CComlib::Bmp2Pic(CString FileName)
{
// CString OutFileName = FileName.Left(FileName.GetLength()-4) + ".raw";
CString OutFileName = FileName.Left(FileName.GetLength()-4) + "_256.pic";
HDIB hDib = ::ReadDIBFile( FileName );
if(hDib == NULL) return;
WORD wHeight,wWidth,wNewWidth;
DWORD dwSize;
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDib);
lpDIBBits=::FindDIBBits(lpDIBHdr);
wHeight=(WORD)(::DIBHeight(lpDIBHdr));
wWidth=(WORD)(::DIBWidth(lpDIBHdr));
wNewWidth=(((wWidth*8)+31)/32)*4;
dwSize=(DWORD)wNewWidth*wHeight;
DWORD dwOffset=dwSize;
unsigned char** uppImage=(unsigned char**)CComlib::fspace_2d(wHeight,wWidth,sizeof(unsigned char));
for(int i=0;i<wHeight;i++)
{
dwOffset-= wNewWidth;
for(int j=0;j<wWidth;j++)
uppImage[i][j]= (unsigned char) ( (*(lpDIBBits+dwOffset+j)));
}
#define SCALE 3
int desR = wHeight/SCALE;
int desC = wWidth/SCALE;
unsigned char ** box = ImgScaleCubicLinear( uppImage , wHeight, wWidth, desR , desC ) ;
ASSERT(box != NULL);
OutputImageWithName( box , desR , desC , OutFileName );
ffree_2d((void**)uppImage,wHeight);
ffree_2d((void**)box, desR);
::GlobalUnlock((HGLOBAL)hDib);
if (hDib != NULL)
{
::GlobalFree((HGLOBAL) hDib);
}
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -