CImg* CDimageView::Dwtstep(CImg* pImg, int Inv) { // 初始化目标图像 CImg* mImg = new CImg(*pImg); mImg->InitPixels(0); int width=pImg->GetWidthPixel(); int height=pImg->GetHeight(); int nMaxWLevel = Log2(width); int nMaxHLevel = Log2(height); int nMaxLevel; if (width == 1<<nMaxWLevel && height == 1<<nMaxHLevel) nMaxLevel = min(nMaxWLevel, nMaxHLevel); // 如果小波变换的存储内存还没有分配,则分配此内存,用double保存graylevel if(!Dwttemp){ Dwttemp = new double[width*height]; // 将图象数据放入m_pDbImage中 for (int i=0; i<height; i++) { for (int j=0; j<width; j++) Dwttemp[i * width + j] = double(pImg->GetGray(j,i)); } } if (!DWTStep_2D(Dwttemp, nMaxWLevel-Curdpth, nMaxHLevel-Curdpth,nMaxWLevel, nMaxHLevel, Inv)) return FALSE; if (Inv) Curdpth --; // 否则加1 else Curdpth ++; BYTE gray; //将double里gray数据转入24位bmp(gray,gray,gray) int lfw = width>>Curdpth, lfh = height>>Curdpth; //尺度区域 for (int i=0; i<height; i++) { for (int j=0; j<width; j++){ if(i<lfh && j<lfw){ //低频X低频,>0直接转 gray = BYTE(Dwttemp[i * width + j]); mImg->SetPixel(j,i,RGB(gray,gray,gray)); } else{ //小于零部分 +128显示 gray = BYTE(Dwttemp[i * width + j]+128); mImg->SetPixel(j,i,RGB(gray,gray,gray)); } } } return mImg; }
CImg CImg::operator | (CImg& gray) { CImg grayRet = *this; int nHeight = GetHeight(); int nWidth = GetWidthPixel(); if(nHeight != gray.GetHeight()) { AfxMessageBox("计算或运算的两幅图像必须具有相同的大小!运算失败,返回原图像。"); return grayRet; } if(nWidth != gray.GetWidthPixel()) { AfxMessageBox("计算或运算的两幅图像必须具有相同的大小!运算失败,返回原图像。"); return grayRet; } // 两幅图像的或 for(int i=0; i<nHeight; i++) { for(int j=0; j<nWidth; j++) { if(gray.GetGray(j, i) == 0) grayRet.SetPixel(j, i, RGB(0, 0, 0)); } } return grayRet; }
CImg CImg::operator ! () { CImg grayRet = *this; grayRet.InitPixels(255); //结果图像置白 int nHeight = GetHeight(); int nWidth = GetWidthPixel(); int i,j; for(i=0; i<nHeight; i++) { for(j=0; j<nWidth; j++) { int pixel = 255 - GetGray(j, i); grayRet.SetPixel(j, i, RGB(pixel, pixel, pixel)); } } return grayRet; }
/******************* CImg CImg::operator - (CImg gray) 功能:图像按位减 参数: CImg 对象 返回值: CImg: 相减后的 CImg 类图像对象 *******************/ CImg CImg::operator - (CImg &gray) { CImg grayRet = *this; //返回图像 //取得图像的高和宽 int nHeight = GetHeight(); int nWidth = GetWidthPixel(); int i, j;//循环变量 //不能在CImg类对象中直接进行像素相减,因为相减的结果可能小于0 vector< vector<int> > GrayMat;//相减后暂存图像的灰度点阵 vector<int> vecRow(nWidth, 0); //GrayMat中的一行(初始化为0) for(i=0; i<nHeight; i++) { GrayMat.push_back(vecRow); } //最大、最小灰度和值 int nMax = -255; int nMin = 255; //逐行扫描图像 for(i=0; i<nHeight; i++) { for(j=0; j<nWidth; j++) { //按位相加 GrayMat[i][j] = GetGray(j, i) - gray.GetGray(j, i); //统计最大、最小值 if( GrayMat[i][j] > nMax) nMax = GrayMat[i][j]; if( GrayMat[i][j] < nMin) nMin = GrayMat[i][j]; }// j }// i //将GrayMat的取值范围重新归一化到[0, 255] int nSpan = nMax - nMin; for(i=0; i<nHeight; i++) { for(j=0; j<nWidth; j++) { BYTE bt; if(nSpan > 0) bt = (GrayMat[i][j] - nMin)*255/nSpan; else if(GrayMat[i][j] <= 255) bt = GrayMat[i][j] ; else bt = 255; grayRet.SetPixel(j, i, RGB(bt, bt, bt)); }// for j }// for i return grayRet; }
CImg* CDimageView::Move(int x, int y ,bool ifresize, CImg* pImg) { CImg* newImg = new CImg(*pImg); //改变新图像大小 int old_width,old_height,width,height; width=old_width=newImg->GetWidthPixel(); height=old_height=newImg->GetHeight(); //if(!ifunchange) //{ // width=old_width+x; // height=old_height+y; // if((width<=0)||(height<=0)) // { // CString test("妈呀,图都被你整没了!"); // CString title("数值有误"); // MessageBox(test,title,0); // return NULL; // } //} if(ifresize) { width=old_width+x; height=old_height+y; newImg->ImResize(height,width); } int i0,j0,i,j; COLORREF color; for(i=0;i<width;i++) for(j=0;j<height;j++) { i0=i-x;j0=j-y; if((i0>=0)&&(i0<old_width)&&(j0>=0)&&(j0<old_height)) { color=pImg->GetPixel(i0,j0); } else { color=RGB(255,255,255); //if(!ifunchange) // color=RGB(255,255,255); //else //{ // if(!ifloop) // color=RGB(255,255,255); // else // { // i0=i0%width; // j0=j0%height; // if(i0<0) // i0+=width; // if(i0>=width) // i0-=width; // if(j0<0) // j0+=height; // if(j0>=height) // j0-=height; // color=pImg->GetPixel(i0,j0); // } //} } newImg->SetPixel(i,j,color); } return newImg; }
CImg* CDimageView::Canny(CImg* pImg) { // 各方向梯度值 // 使用Prewitt模板计算各个方向上的梯度值 CImg* imgGH=PrewittEdge(pImg,1); CImg* imgGV=PrewittEdge(pImg,2); CImg* imgGCW=PrewittEdge(pImg,3); CImg* imgGCCW=PrewittEdge(pImg,4); CImg* imgGratitude = new CImg(*pImg); imgGratitude->InitPixels(0); int width=pImg->GetWidthPixel(); int height=pImg->GetHeight(); // 最大梯度方向 BYTE * pbDirection = new BYTE [height * width]; memset(pbDirection, 0,height * width * sizeof(BYTE)); // 寻找每点的最大梯度方向并写入对应的最大梯度值 for (int i=0; i<height; i++) { for (int j=0; j<width; j++) { BYTE gray = 0; if (imgGH->GetGray(j, i) > gray) { gray = imgGH->GetGray(j, i); pbDirection[i * width + j] = 1; imgGratitude->SetPixel(j, i, RGB(gray, gray, gray)); } if (imgGV->GetGray(j, i) > gray) { gray = imgGV->GetGray(j, i); pbDirection[i * width + j] = 2; imgGratitude->SetPixel(j, i, RGB(gray, gray, gray)); } if (imgGCW->GetGray(j, i) > gray) { gray = imgGCW->GetGray(j, i); pbDirection[i * width + j] = 3; imgGratitude->SetPixel(j, i, RGB(gray, gray, gray)); } if (imgGCCW->GetGray(j, i) > gray) { gray = imgGCCW->GetGray(j, i); pbDirection[i * width + j] = 4; imgGratitude->SetPixel(j, i, RGB(gray, gray, gray)); } } } // 阈值化时重用前面的对象 CImg *pImgThreL = imgGH, *pImgThreH = imgGV; // 检查阈值参数,如未给出阈值则计算以取得最佳阈值 int bThreH; int bThreL; bThreH = 1.2 * imgGratitude->DetectThreshold(100); bThreL = 0.4 * bThreH; // 将最大梯度图像按高低值分别进行阈值化 imgGratitude->Threshold(pImgThreL, bThreL); imgGratitude->Threshold(pImgThreH, bThreH); // 初始化目标图像 CImg* mImg = new CImg(*pImg); mImg->InitPixels(0); // 根据低阈值图像在高阈值图像上进行边界修补 for (int i=1; i<height-1; i++) { for (int j=1; j<width-1; j++) { if (pImgThreH->GetGray(j, i)) { // 高阈值图像上发现点直接确定 mImg->SetPixel(j, i, RGB(255, 255, 255)); // 搜索梯度最大方向上的邻域 switch ( pbDirection[i * width + j] ) { case 1: // 水平方向 if (pImgThreL->GetGray(j+1, i)) { pImgThreH->SetPixel(j+1, i, RGB(255, 255, 255)); } if (pImgThreL->GetGray(j-1, i)) { pImgThreH->SetPixel(j-1, i, RGB(255, 255, 255)); } break; case 2: // 垂直方向 if (pImgThreL->GetGray(j, i+1)) { pImgThreH->SetPixel(j, i+1, RGB(255, 255, 255)); } if (pImgThreL->GetGray(j, i-1)) { pImgThreH->SetPixel(j, i-1, RGB(255, 255, 255)); } break; case 3: // 45度方向 if (pImgThreL->GetGray(j+1, i-1)) { pImgThreH->SetPixel(j+1, i-1, RGB(255, 255, 255)); } if (pImgThreL->GetGray(j-1, i+1)) { pImgThreH->SetPixel(j-1, i+1, RGB(255, 255, 255)); } break; case 4: // 135度方向 if (pImgThreL->GetGray(j+1, i+1)) { pImgThreH->SetPixel(j+1, i+1, RGB(255, 255, 255)); } if (pImgThreL->GetGray(j-1, i-1)) { pImgThreH->SetPixel(j-1, i-1, RGB(255, 255, 255)); } break; } }//if }//for j }//for i delete pbDirection; return mImg; }