📄 myimagedbdoc.cpp
字号:
imageData[pos*3+2] = 0;
}
}
}
}
RefreshImageObject();
delete [] tempdirect; tempdirect = NULL;
delete [] tempitensity; tempitensity = NULL;
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
void CMyImageDBDoc::OnEntropy()
{
BeginWaitCursor();
//存放各点邻域信息;
FLOAT* tempentropy = new FLOAT[imageWidth*imageHeight];
for (INT y=0; y<imageHeight; y++)
{
for (INT x=0; x<imageWidth; x++)
{
INT temppos = y*imageWidth + x;
BYTE* neiarr=NULL;
INT tempnr = NEIRADIUS;
GetNearPixelsGreenExt(x, y, imageData
, imageWidth, imageHeight, tempnr
, &neiarr);//计算邻域
INT tempi = 2*tempnr + 1;
tempentropy[temppos] = myTexture.CalcuEntropy(
neiarr, tempi, tempi);
delete [] neiarr; neiarr = NULL;
}
}
//用临时数组替换原数组;
for (y=0; y<imageHeight; y++)
{
for (INT x=0; x<imageWidth; x++)
{
LONG pos = (y*imageWidth + x);
BYTE tempval = (BYTE)(tempentropy[pos]*30);
imageData[pos*3] = tempval;
imageData[pos*3+1] = tempval;
imageData[pos*3+2] = tempval;
}
}
RefreshImageObject();
delete [] tempentropy; tempentropy = NULL;
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
void CMyImageDBDoc::OnDirectionHisAll()
{
BeginWaitCursor();
FLOAT* xyzdatas = new FLOAT[imageWidth*imageHeight*3];//存放返回的方向数据;
//存放各点邻域信息;
INT binscount = 0;
INT tempnr = NEIRADIUS;
INT tempi = 2*tempnr + 1;
INT ptcounts = tempi * tempi;
FLOAT mutifactor = 255 / (FLOAT)ptcounts;
for (INT y=0; y<imageHeight; y++)
{
for (INT x=0; x<imageWidth; x++)
{
INT temppos = y*imageWidth + x;
BYTE* neiarr=NULL;
GetNearPixelsGreenExt(x, y, imageData
, imageWidth, imageHeight, tempnr
, &neiarr);//计算邻域
myTexture.GetDirectionReal(neiarr
, tempi, tempi
, xyzdatas[temppos*3]//方向
, xyzdatas[temppos*3+1]//强度
, xyzdatas[temppos*3+2]);//方差
delete [] neiarr; neiarr = NULL;
}
}
//用临时数组替换原数组;
for (y=0; y<imageHeight; y++)
{
for (INT x=0; x<imageWidth; x++)
{
LONG pos = (y*imageWidth + x) * 3;
imageData[pos] = (BYTE) ( 0 );
imageData[pos+1] = 255 - (BYTE) ( xyzdatas[pos+2]*200);
imageData[pos+2] = (BYTE) ( 0 );
}
}
RefreshImageObject();
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
void CMyImageDBDoc::OnHsiPic()
{
BeginWaitCursor();
MyLUV* luvbuf = new MyLUV[imageWidth*imageHeight];
FLOAT* xyzbuff = NULL;
xyzbuff = new FLOAT[imageWidth*imageHeight*3];
myColorSpace.RgbtoLuvPcm(imageData, imageWidth
, imageHeight, luvbuf);
INT x, y, pos;
x = y = pos = 0;
for (y=0; y<imageHeight; y++)
{
for (x=0; x<imageWidth; x++)
{
pos = y*imageWidth + x;
xyzbuff[pos*3] = 75;//luvbuf[pos].l;
xyzbuff[pos*3+1] = luvbuf[pos].u;
xyzbuff[pos*3+2] = luvbuf[pos].v;
}
}
myColorSpace.LuvToRgb(xyzbuff, imageWidth
, imageHeight, imageData);
delete [] luvbuf; luvbuf = NULL;
delete [] xyzbuff; xyzbuff = NULL;
RefreshImageObject();
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
void CMyImageDBDoc::OnReverseCopy()
{
BeginWaitCursor();
INT width = min(imageWidth, imageHeight);
if (!myMath.isOdd(width))
{
width -= 1;
}
BYTE* gchannel = new BYTE[width*width];
//取图像中左上角大小为width*width的块(G通道);
INT pos, posor;
for (INT y=0; y<width; y++)
{
for(INT x=0; x<width; x++)
{
pos = y*width + x;
posor = y*imageWidth + x;//在原图像中的位置;
gchannel[pos] = imageData[posor*3+1];
}
}
BYTE* gchannel2 = new BYTE[width*width];
myMath.RevertCopyMatrix(gchannel
, width, gchannel2, 3, 1);
delete [] imageData; imageData = NULL;
imageData = new BYTE[width*width*3];
for (y=0; y<width; y++)
{
for(INT x=0; x<width; x++)
{
pos = y*width + x;
imageData[pos*3] = gchannel2[pos];
imageData[pos*3+1] = gchannel2[pos];
imageData[pos*3+2] = gchannel2[pos];
}
}
delete [] gchannel; gchannel = NULL;
delete [] gchannel2; gchannel2 = NULL;
imageWidth = width;
imageHeight = width;
RefreshImageObject();
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
#define BREAKBIAS 3//突变条件;
void CMyImageDBDoc::OnOrderDetect()
{
//1、设置起始点startpt,向前扫描检测突变点breakpt;
//2、计算起始点与突变点间基元curunit的相关参量average、len等等;
//3、检测预测标志;
//4、若已设,则判断是否符合预测条件,若符合则归并到前一纹理区,并设置下一步预测条件;
//5、否则,在前面的新基元(多个区域)中搜索相似基元simiunit;
//6、若无,则建立新基元newunit(k),记录该基元的各参数,将突变点设为新的起始点,开始新的搜索;
//7、若有,则观察前一新基元newunit(k-1)与相似基元simiunit的前一基元的相似性;
//8、若相似,则判为纹理(归并到一个区域),设置其parent, 设置预测标志及满足预测的条件;
//9、否则,同第4步;
//突变点利用二阶导数的绝对值加以判定;
BeginWaitCursor();
BYTE* linedata = new BYTE[imageWidth];
BYTE* errdata = new BYTE[imageWidth];//各点一阶差分;
BYTE* diffdata = new BYTE[imageWidth];//各点二阶差分;
for (INT y=0; y<imageHeight; y++)
{
INT linestart = y*imageWidth;
//读入一行数据;
for (INT x=0; x<imageWidth; x++)
{
INT pos = linestart + x;
linedata[x] = imageData[pos*3+1];
}
//处理该行数据;
//计算每一点与前一点的差值;
errdata[0] = 0;
for (x=1; x<imageWidth; x++)
{
errdata[x] = abs(linedata[x] - linedata[x-1]);
}
//计算二阶差分;
diffdata[0] = 0;
for (x=1; x<imageWidth-1; x++)
{
diffdata[x] = abs( errdata[x+1] - errdata[x] );
}
diffdata[imageWidth-1] = diffdata[imageWidth-2];
/*
//二阶差分值写入图像;
for (x=0; x<imageWidth; x++)
{
INT pos = (linestart + x) * 3;
if (errdata[x]>12)
{
imageData[pos] = 250;
imageData[pos+1] = 250;
imageData[pos+2] = 250;
}else
{
imageData[pos] = 0;
imageData[pos+1] = 0;
imageData[pos+2] = 0;
}
}
*/
}
delete [] diffdata; diffdata = NULL;
delete [] errdata; errdata = NULL;
delete [] linedata; linedata = NULL;
//////////////////////////////////////////////////////////////////////////
//以下首先计算各区间参数,然后进行规则纹理检测;
//////////////////////////////////////////////////////////////////////////
INT stpt, bkpt;//起始点,突变点,预测标志;
stpt = bkpt = 0;
INT bknum = 0;//突变点数;
INT* bkposarr = NULL;//突变点位置;bk[0]为第一个突变点位置(起始点),依此类推;
FLOAT cuaver = -1;//当前均值;
INT culen = -1;//当前基元长度;
FLOAT preavermin = 255;//预测条件均值最小值;
FLOAT preavermax = 0;//预测条件均值最大值;
INT prelenmin = 100;//预测条件区间长度最小值;
INT prelenmax = 0;//预测条件区间长度最大值;
MyReguTex* pretexrgarr = NULL;//前一纹理区;
MyReguTex* prenewtexsarr = NULL;//前置的新纹理s;
INT prenewtexnum = 0;//前置新纹理的数目;
MyReguTex* rgtexsarr = NULL;//各种纹理基元列表,基元在数组中的位置对应该基元的索引标识号;
MyReguTex* scanedrgarr = NULL;//已扫描区域链表;
//////////////////////////////////////////////////////////////////////////
//各区间参数计算;
//////////////////////////////////////////////////////////////////////////
INT rgnum = bknum;//区间数等于突变点数;
FLOAT* averarr = new FLOAT[rgnum];//存放各区间均值;
INT* lenarr = new INT[rgnum];//存放各区间长度;
for (INT i=0; i<rgnum; i++)
{
averarr[i] = 0;
//计算一个区间的参数;
for (INT x=bkposarr[i]; x<bkposarr[i+1]; x++)
{
averarr[i] += linedata[x];
}
lenarr[i] = bkposarr[i+1] - bkposarr[i];//该区间长度;
averarr[i] = averarr[i] / lenarr[i];//该区间均值;
}
//////////////////////////////////////////////////////////////////////////
//以下检测规律性
//////////////////////////////////////////////////////////////////////////
//3、检测预测标志;
//4、若已设,则判断是否符合预测条件,若符合则归并到前一归并纹理区,并设置下一步预测条件;
//5、否则,在紧靠前的新基元(直到前一归并纹理区)中搜索相似基元simiunit;
//6、若无,则建立新基元newunit(k),记录该基元的各参数,将突变点设为新的起始点,开始新的搜索;
//7、若有,则观察前一新基元newunit(k-1)与相似基元simiunit的前一基元的相似性;
//8、若相似,则判为纹理(归并到一个区域),设置其parent, 设置预测标志及满足预测的条件;
//9 、否则,同第4步;
// 扫描线(已扫描区域)包括两种元素,
// A、归并纹理区,每一归并纹理区包括该区区号,纹理的索引标识号,
//起终点pos,起点和终点子纹理标识以及该区的一些其它统计量;
// B、新纹理区,为独立的不规则基元,其基元纹理parent与child均为空,
//每一新纹理区包括该基元的索引标识号,起点和终点pos,以及其它统计量;
// 另建一个纹理列表,包括所有归并纹理与新纹理,可根据纹理索引
//标识号在该表中检索到相应纹理;
using namespace std;
list <LineElement> scanedline;
list <LineElement>::iterator scanedlineiter;
list <LineElement>::iterator newrgstiter;//紧靠前的新纹理区中的第一个位置;
list <LineElement>::iterator prenewrgiter;//当前新纹理区的前一个新纹理区;
list <MyReguTex> texlist;//纹理列表;
list <MyReguTex>::iterator texlistiter;
LineElement curel;//当前元素;
MyReguTex curtex;//当前基元;
INT curpos=0;
BOOL preflag = FALSE;//预测标志;
for (i=0; i<rgnum; i++)
{
//首先建当前元素与当前基元;
INT tempid = texlist.size() + 1;
curtex.SetValue(tempid, 0, averarr[i]
, lenarr[i], -1, -1);
curel.averval = averarr[i];
curpos += lenarr[i];
curel.stpos += curpos - lenarr[i];
curel.endpos = curpos;
curel.iscombined = FALSE;//初始设为非归并纹理区;
curel.len = lenarr[i];
curel.rgid = i;//备用;
curel.texindexid = texlist.size() + 1;//
if (preflag)
{
//判断是否符合预定条件;
BOOL issatify = (averarr[i]<=preavermax)
&& (averarr[i]>=preavermin) && (lenarr[i]<=prelenmax)
&& (lenarr[i]>=prelenmin);
if (issatify)
{
//归并到前一归并纹理区,更改前一纹理区的相应参数,并设预测条件;
LineElement lastel = scanedline.back();
/*
将该归并纹理区长度增加,更新起终点pos,
起点和终点子纹理标识以及该区的一些其它统计量
设置下一步的预测标志及检测条件;
*/
lastel.endpos += curel.len;
preflag = TRUE;
}else
{
//创建新纹理区,加到scanedline中去,并清预测条件;
LineElement tempel;
tempel.averval = 0;
scanedline.push_back(tempel);
preflag = FALSE;
//所建新纹理区为所有新纹理区中的第一个,记录该位置
//以便后续的搜索;
newrgstiter = scanedline.end();
}
}else
{
//在紧靠前的多个新纹理区中搜索相似区
BOOL isfdsim = FALSE;
for (scanedlineiter=newrgstiter; scanedlineiter!=scanedline.end(); scanedlineiter++)
{
LineElement tempel = *scanedlineiter;
if (tempel.texindexid==curel.texindexid)
{
isfdsim = TRUE;
scanedlineiter = scanedlineiter;//保留这一位置;
break;
}
}
if (!isfdsim)
{
//没找到,则创建新纹理区,加入到扫描线中去,并清预测条件;
texlist.push_back(curtex);//在纹理列表中加入新纹理;
scanedline.push_back(curel);//当前元素区加入扫描线;
preflag = FALSE;
}else
{
//继续检查前置区的相似性
BOOL ispresim = FALSE;
//得到前一个新纹理;
LineElement preel = scanedline.back();//即为扫描线中的最后一个;
//首先判断是否为归并纹理区;
if (preel.iscombined)
{
ispresim = FALSE;//前一个为归并纹理区,不可能相似;
}else{
//前一个为新纹理区,以下判断是否相似;
if (preel.texindexid == curtex.myIndexid)
{
ispresim = TRUE;
}else{
ispresim = FALSE;
}
}
if (ispresim)
{
//若仍然相似,则判为规则纹理,创建新的归并纹理区,并置预测标志与条件;
scanedline.push_back(curel);
//注意要更新当前纹理与其父子纹理之间的关系;
texlist.push_back(curtex);
preflag = TRUE;
}else
{
//若不相似,则与没有找到相似区一样,创建新纹理区,并清预测条件;
scanedline.push_back(curel);
preflag = FALSE;
//注意此处不需加入在纹理列表中加入新纹理;
}
}
}
}
RefreshImageObject();
CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->GetMainWnd();
EndWaitCursor();
pFrame->pImageView->Invalidate(FALSE);
}
/*****************************************************************************
* 函数名称:LocalThresholding()
*
* 参数: BYTE* buf -- 指向存放位图象素值的指针
* int nWidth -- 位图宽度
* int nHeight -- 位图高度
* int nTempWidth -- 窗口宽度,默认为7
* int nTempHeight -- 窗口高度,默认为7
*
* 返回值: BOOL
*
* 说明: 该函数用于256色灰度位图的二值化,用一种快速局部方法进行阈值选取
* 处理完后,buf中存放二值化后的图象。
*
******************************************************************************/
BOOL CMyImageDBDoc::LocalThresholding(BYTE* buf,int nWidth,int nHeight,
int nTempWidth/* =7 */,int nTempHeight/* =7 */,
int nTempCenX/* =3*/,int nTempCenY/* =3*/)
{
int i,j; // 循环变量
int h[256]; // 灰度直方图数组
int nValue; // 当前灰
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -