⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myimagedbdoc.cpp

📁 这是一个分水岭程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					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 + -