#include<atlimage.h> #define pi 3.1415926 class CDigitalImageProcess { public: CDigitalImageProcess(void); //CDigitalImageProcess(CString FileName); ~CDigitalImageProcess(void); //加载图像如BMP,JPG HRESULT Load(LPCTSTR pszFileName); //显示加载图像 //hDestDC为目标DC,xDest,yDest为要显示图片的位置(左上角坐标) BOOL Show(HDC hDestDC,int xDest, int yDest); //显示处理后图像 //hDestDC为目标DC,xDest,yDest为要显示图片的位置(左上角坐标) BOOL ShowProcessedImage(HDC hDestDC,int xDest, int yDest); //创建直方图,type指明哪个通道的直方图type == 1为红色通道,type == 1为绿色通道,type == 2为蓝色通道 void CreateHistogram(int type); //显示源图像直方图,type指明哪个通道的直方图type == 1为红色通道,type == 1为绿色通道,type == 2为蓝色通道 //xDest,yDest为要显示图片的位置(左上角坐标)直方图高度为300,宽度为516 BOOL ShowHistogram(CDC * pDC,int xDest, int yDest, int type); //对直方图进行均衡化 void BlanceHistogram(); /*BOOL ShowProcessedHistogram(CDC * pDC,int xDest, int yDest);*/ //删除图像 void Destory(); //去除红眼 void RemoveRedEye(); //加大对比度scale指定程度 void IncreaseContract(double scale); //形变 void ChangeShape(double angle, double xMove, double yMove); //错切 void Shear(int xShear, int yShear); //保存 HRESULT Save(LPCTSTR pszFileName,REFGUID guidFileType); private: //源图像 CImage m_Image; //处理后图像 CImage m_ImageProcessed; //源图像直方图矩阵 double PixelRArray[256]; double PixelGArray[256]; double PixelBArray[256]; //处理后图像直方图矩阵 double NewRPixelArray[256]; double NewGPixelArray[256]; double NewBPixelArray[256]; }; #include "StdAfx.h" #include "DigitalImageProcess.h" #include<cmath> #include<stdlib.h> CDigitalImageProcess::CDigitalImageProcess(void) { } CDigitalImageProcess::~CDigitalImageProcess(void) { } //CDigitalImageProcess::CDigitalImageProcess(CString FileName) //{ // m_Image.Load(FileName); //} HRESULT CDigitalImageProcess::Load(LPCTSTR pszFileName) { return m_Image.Load(pszFileName); } BOOL CDigitalImageProcess::Show(HDC hDestDC,int xDest, int yDest) { return m_Image.BitBlt(hDestDC, xDest, yDest, SRCCOPY); } BOOL CDigitalImageProcess::ShowHistogram(CDC * pDC, int xDest, int yDest, int type) { double Max= 0; switch(type) { case 1://red for(int i = 0; i< 256; ++i) { if(Max < PixelRArray[i]) { Max = PixelRArray[i]; } } pDC->Rectangle(xDest, yDest, xDest + 516,yDest + 300); pDC->TextOutW(xDest,yDest, _T("RED")); for(int i = 0;i<256;++i) { pDC->MoveTo(xDest + 2 * i + 2, yDest + 300); pDC->LineTo(xDest +2 * i + 2, yDest + 300 - static_cast<int>( (PixelRArray[i]) / Max * 300)); } break; case 2://green for(int i = 0; i< 256; ++i) { if(Max < PixelGArray[i]) { Max = PixelGArray[i]; } } pDC->Rectangle(xDest, yDest, xDest + 516,yDest + 300); pDC->TextOutW(xDest,yDest, _T("GREEN")); for(int i = 0;i<256;++i) { pDC->MoveTo(xDest + 2 * i + 2, yDest + 300); pDC->LineTo(xDest +2 * i + 2, yDest + 300 - static_cast<int>((PixelGArray[i]) / Max * 300)); } break; case 3://blue for(int i = 0; i< 256; ++i) { if(Max < PixelBArray[i]) { Max = PixelBArray[i]; } } pDC->Rectangle(xDest, yDest, xDest + 516,yDest + 300); pDC->TextOutW(xDest,yDest, _T("BLUE")); for(int i = 0;i<256;++i) { pDC->MoveTo(xDest + 2 * i + 2, yDest + 300); pDC->LineTo(xDest +2 * i + 2, yDest + 300 - static_cast<int>((PixelBArray[i]) / Max * 300)); } break; default : return FALSE; } return TRUE; } void CDigitalImageProcess::BlanceHistogram() { int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); for(int i = 0; i<256; ++i) { PixelRArray[i] = 0; PixelGArray[i] = 0; PixelBArray[i] = 0; NewRPixelArray[i] = 0; NewGPixelArray[i] = 0; NewBPixelArray[i] = 0; } for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { ++PixelRArray[GetRValue(m_Image.GetPixel(i,j))]; ++PixelGArray[GetGValue(m_Image.GetPixel(i,j))]; ++PixelBArray[GetBValue(m_Image.GetPixel(i,j))]; } for(int i = 0; i<256; ++i) { PixelRArray[i] /= iWidth * iHight; PixelGArray[i] /= iWidth * iHight; PixelBArray[i] /= iWidth * iHight; } for(int i = 0; i<256; ++i) { double tmpR = 0; double tmpG = 0; double tmpB = 0; for(int j = 0; j<i; ++j) { tmpR += PixelRArray[j]; tmpG += PixelGArray[j]; tmpB += PixelBArray[j]; } NewRPixelArray[i] = tmpR; NewGPixelArray[i] = tmpG; NewBPixelArray[i] = tmpB; } for(int i = 0; i<256; ++i) { NewRPixelArray[i] *= 255; NewGPixelArray[i] *= 255; NewBPixelArray[i] *= 255; } m_ImageProcessed.CreateEx(iWidth,iHight,32,BI_RGB); for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { m_ImageProcessed.SetPixel(i, j, RGB( static_cast<int>(NewRPixelArray[GetRValue(m_Image.GetPixel(i,j))]), static_cast<int>(NewGPixelArray[GetGValue(m_Image.GetPixel(i,j))]), static_cast<int>(NewBPixelArray[GetBValue(m_Image.GetPixel(i,j))]) ) ); } } //BOOL CDigitalImageProcess::ShowProcessedHistogram(CDC *pDC, int xDest, int yDest) //{ // // return m_ImageProcessed.BitBlt(pDC->m_hDC, xDest, yDest, SRCCOPY); // // //} void CDigitalImageProcess::CreateHistogram(int type) { int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); switch(type) { case 0: for(int i = 0; i<256; ++i) { PixelRArray[i] = 0; } for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { ++PixelRArray[GetRValue(m_Image.GetPixel(i,j))]; } break; case 1: for(int i = 0; i<256; ++i) { PixelGArray[i] = 0; } for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { ++PixelGArray[GetGValue(m_Image.GetPixel(i,j))]; } break; case 2: for(int i = 0; i<256; ++i) { PixelBArray[i] = 0; } for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { ++PixelBArray[GetBValue(m_Image.GetPixel(i,j))]; } break; default: break; } } void CDigitalImageProcess::Destory() { m_Image.Destroy(); m_ImageProcessed.Destroy(); } void CDigitalImageProcess::RemoveRedEye() { int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); double R1,G1,B1; double angle,H1,S1,I1; m_ImageProcessed.CreateEx(iWidth,iHight,32,BI_RGB); for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { R1 = GetRValue(m_Image.GetPixel(i,j)); G1 = GetGValue(m_Image.GetPixel(i,j)); B1 = GetBValue(m_Image.GetPixel(i,j)); //////////////////////////////RGB2HSI///////////////////////////////////////////////////////////////////// double tmp = (2*sqrt(pow(R1-G1,2)+(R1-B1)*(G1-B1))); if(tmp ==0) tmp = 1; angle = acos((R1-G1+R1-B1)/tmp); if(angle < 0) { //AfxMessageBox(_T("d")); break; } if(B1>G1) { H1 = 2*pi - angle; } else { H1 = angle; } S1 = 1 - 3*__min(__min(R1,G1),B1)/(R1 + G1 + B1); I1 = (R1 + G1 + B1)/3; ///////////////////////////////RGB2HSI///////////////////////////////////////////////////////////////////////////// //消红眼不管用 if(H1 > (- pi/4) && H1 < pi/4 && S1 > 0.3) { S1 = 0; } ///////////////////////////////HSI2RGB///////////////////////////////////////////////////////////////////////////////////// if(H1>=0 && H1<pi*2/3) { B1 = I1 * (1 - S1); R1 = I1 * (1+ S1 * cos(H1) / cos(pi/3 - H1)); G1 = 3 * I1 - (R1 + B1); }else if(H1 >= pi * 2 / 3 && H1 < pi * 4 / 3) { H1 -= pi * 2 / 3; R1 = I1 * (1 - S1); G1 = I1 * (1+ S1 * cos(H1) / cos(pi/3 - H1)); B1 = 3 * I1 - (R1 + G1); }else { H1 -= pi * 4 / 3; G1 = I1 * (1 - S1); B1 = I1 * (1+ S1 * cos(H1) / cos(pi/3 - H1)); R1 = 3 * I1 - (B1 + G1); } ///////////////////////////////////HSI2RGB////////////////////////////////////////////////////////////////////////////////////// m_ImageProcessed.SetPixel(i, j, RGB(R1, G1, B1)); } } BOOL CDigitalImageProcess::ShowProcessedImage(HDC hDestDC,int xDest, int yDest) { return m_ImageProcessed.BitBlt(hDestDC, xDest, yDest); } void CDigitalImageProcess::IncreaseContract(double scale) { int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); double R1,G1,B1; m_ImageProcessed.CreateEx(iWidth,iHight,32,BI_RGB); for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { R1 = GetRValue(m_Image.GetPixel(i,j)); G1 = GetGValue(m_Image.GetPixel(i,j)); B1 = GetBValue(m_Image.GetPixel(i,j)); R1 = R1 + scale * R1 * (255 - R1); G1 = G1 + scale * G1 * (255 - G1); B1 = B1 + scale * B1 * (255 - B1); m_ImageProcessed.SetPixel(i, j, RGB(R1, G1, B1)); } } void CDigitalImageProcess::ChangeShape(double angle, double xMove, double yMove) { double angle1 = angle * 2 * pi / 360; int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); double R1,G1,B1; double r = sqrt(static_cast<double>(iWidth * iWidth + iHight * iHight)); m_ImageProcessed.CreateEx(static_cast<int>(r + 20 + xMove),static_cast<int>(r + 20 + yMove),32,BI_RGB); int NewX,NewY; for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { R1 = GetRValue(m_Image.GetPixel(i,j)); G1 = GetGValue(m_Image.GetPixel(i,j)); B1 = GetBValue(m_Image.GetPixel(i,j)); NewX = static_cast<int>((i - iWidth / 2) * cos(angle1) - (j - iHight / 2) * sin(angle1)); NewY = static_cast<int>((i - iWidth / 2) * sin(angle1) + (j - iHight / 2) * cos(angle1)); m_ImageProcessed.SetPixel(NewX + static_cast<int>(r /2 + xMove), NewY + static_cast<int>(r /2 + xMove), RGB(R1, G1, B1)); } for(int i = 1; i< m_ImageProcessed.GetWidth() - 1; ++i) for(int j = 1; j<m_ImageProcessed.GetHeight() - 1; ++j) { R1 = GetRValue(m_ImageProcessed.GetPixel(i,j)); G1 = GetGValue(m_ImageProcessed.GetPixel(i,j)); B1 = GetBValue(m_ImageProcessed.GetPixel(i,j)); if(R1 == 0 && G1 == 0 && B1 == 0) { R1 = GetRValue(m_ImageProcessed.GetPixel(i + 1,j)) + GetRValue(m_ImageProcessed.GetPixel(i - 1,j)); G1 = GetGValue(m_ImageProcessed.GetPixel(i + 1,j)) + GetGValue(m_ImageProcessed.GetPixel(i - 1,j)); B1 = GetBValue(m_ImageProcessed.GetPixel(i + 1,j)) + GetBValue(m_ImageProcessed.GetPixel(i - 1,j)); m_ImageProcessed.SetPixel(i,j, RGB(R1 / 2, G1 / 2, B1 / 2)); } } } void CDigitalImageProcess::Shear(int xShear, int yShear) { int iWidth,iHight; iWidth = m_Image.GetWidth(); iHight = m_Image.GetHeight(); double R1,G1,B1; m_ImageProcessed.CreateEx(iWidth * (abs(xShear) + 1), iHight * (abs(yShear) + 1), 32 , BI_RGB); int NewX,NewY; for(int i = 0; i< iWidth; ++i) for(int j = 0; j<iHight; ++j) { R1 = GetRValue(m_Image.GetPixel(i,j)); G1 = GetGValue(m_Image.GetPixel(i,j)); B1 = GetBValue(m_Image.GetPixel(i,j)); NewX = i + xShear * j ; NewY = j + yShear * i ; if(xShear < 0) { NewX += iWidth * abs(xShear); } if(yShear < 0) { NewY += iHight * abs(yShear); } m_ImageProcessed.SetPixel(NewX, NewY, RGB(R1, G1, B1)); } } HRESULT CDigitalImageProcess::Save(LPCTSTR pszFileName, const GUID &guidFileType) { return m_ImageProcessed.Save(pszFileName,guidFileType); }