📄 image.cpp
字号:
// Image.cpp: implementation of the CImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "math.h"
#include "afxtempl.h"
#include "ShowImg.h"
#include "ShowProcedure.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define ROUND(X) (((X)-int(X))>0.5?int(X)+1:int(X))
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImage::CImage()
{
m_pR = NULL;
m_pG = NULL;
m_pB = NULL;
m_bRGB = FALSE;
m_nHeight = 0;
m_nWidth = 0;
m_nPixelNum = 0;
m_pShowDlg = NULL;
}
BOOL CImage::IsRGB()
{
return m_bRGB;
}
BOOL CImage::Thinner(CImage &ImgOut)
{
if (!ImgOut.Create(CSize(m_nWidth,m_nHeight),FALSE))
{
return FALSE;
}
//四个条件
BOOL bCondition1;
BOOL bCondition2;
BOOL bCondition3;
BOOL bCondition4;
//计数器
int nCount;
//5×5相邻区域像素值
int neighbour[5][5];
for (int i=0;i<m_nHeight;i++)
{
for (int j=0;j<m_nWidth;j++)
{
ImgOut.m_pR[i*m_nWidth+j]= m_pR[i*m_nWidth+j];
}
}
for (i=0;i<m_nHeight;i++)
{
for (int j=0;j<m_nWidth;j++)
{
bCondition1 = FALSE;
bCondition2 = FALSE;
bCondition3 = FALSE;
bCondition4 = FALSE;
//如果源图像中当前点为白色,则跳过
if (m_pR[i*m_nWidth+j] == 255)
{
continue;
}
//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for (int ii=i-2;ii<=i+2;ii++)
{
for (int jj=j-2;jj<=j+2;jj++)
{
if (ii>=0 && ii<m_nHeight && jj>=0 && jj<m_nWidth )
neighbour[ii-i+2][jj-j+2] = 1-m_pR[ii*m_nWidth+jj]/255;
else
neighbour[ii-i+2][jj-j+2] = 1;
}
}
// neighbour[][]
//逐个判断条件。
//判断2<=NZ(P1)<=6
nCount = neighbour[1][1] + neighbour[1][2] + neighbour[1][3] \
+ neighbour[2][1] + neighbour[2][3] + \
+ neighbour[3][1] + neighbour[3][2] + neighbour[3][3];
if ( nCount >= 2 && nCount <=6)
bCondition1 = TRUE;
//判断Z0(P1)=1
nCount = 0;
if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
nCount++;
if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
nCount++;
if (neighbour[2][1] == 0 && neighbour[3][1] == 1)
nCount++;
if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
nCount++;
if (neighbour[3][2] == 0 && neighbour[3][3] == 1)
nCount++;
if (neighbour[3][3] == 0 && neighbour[2][3] == 1)
nCount++;
if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
nCount++;
if (neighbour[1][3] == 0 && neighbour[1][2] == 1)
nCount++;
if (nCount == 1)
bCondition2 = TRUE;
//判断P2*P4*P8=0 or Z0(p2)!=1
if (neighbour[1][2]*neighbour[2][1]*neighbour[2][3] == 0)
bCondition3 = TRUE;
else
{
nCount = 0;
if (neighbour[0][2] == 0 && neighbour[0][1] == 1)
nCount++;
if (neighbour[0][1] == 0 && neighbour[1][1] == 1)
nCount++;
if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
nCount++;
if (neighbour[2][1] == 0 && neighbour[2][2] == 1)
nCount++;
if (neighbour[2][2] == 0 && neighbour[2][3] == 1)
nCount++;
if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
nCount++;
if (neighbour[1][3] == 0 && neighbour[0][3] == 1)
nCount++;
if (neighbour[0][3] == 0 && neighbour[0][2] == 1)
nCount++;
if (nCount != 1)
bCondition3 = TRUE;
}
//判断P2*P4*P6=0 or Z0(p4)!=1
if (neighbour[1][2]*neighbour[2][1]*neighbour[3][2] == 0)
bCondition4 = TRUE;
else
{
nCount = 0;
if (neighbour[1][1] == 0 && neighbour[1][0] == 1)
nCount++;
if (neighbour[1][0] == 0 && neighbour[2][0] == 1)
nCount++;
if (neighbour[2][0] == 0 && neighbour[3][0] == 1)
nCount++;
if (neighbour[3][0] == 0 && neighbour[3][1] == 1)
nCount++;
if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
nCount++;
if (neighbour[3][2] == 0 && neighbour[2][2] == 1)
nCount++;
if (neighbour[2][2] == 0 && neighbour[1][2] == 1)
nCount++;
if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
nCount++;
if (nCount != 1)
bCondition4 = TRUE;
}
if(bCondition1 && bCondition2 && bCondition3 && bCondition4)
{
ImgOut.m_pR[i*m_nWidth+j] = BYTE(255);
}
}
}
return TRUE;
}
CImage::CImage(CImage &Source)
{
m_pShowDlg = NULL;
m_pR = NULL;
m_pG = NULL;
m_pB = NULL;
m_bRGB = FALSE;
m_nHeight = 0;
m_nWidth = 0;
m_nPixelNum = 0;
if (!Create(CSize(Source.GetWidth(),Source.GetHeight()),Source.IsRGB()))
{
return ;
}
memcpy(m_pR,Source.m_pR,m_nPixelNum);
if (m_bRGB)
{
memcpy(m_pG,Source.m_pG,m_nPixelNum);
memcpy(m_pB,Source.m_pB,m_nPixelNum);
}
}
CImage& CImage::operator =(CImage &Source)
{
if (!Create(CSize(Source.GetWidth(),Source.GetHeight()),Source.IsRGB()))
{
return *this;
}
memcpy(m_pR,Source.m_pR,m_nPixelNum);
if (m_bRGB)
{
memcpy(m_pG,Source.m_pG,m_nPixelNum);
memcpy(m_pB,Source.m_pB,m_nPixelNum);
}
return *this;
}
int CImage::GetHeight()
{
return m_nHeight;
}
int CImage::GetWidth()
{
return m_nWidth;
}
void CImage::Detroy()
{
if (m_pR)
{
delete[]m_pR;
m_pR = NULL;
}
if (m_pG)
{
delete[]m_pG;
m_pG = NULL;
}
if (m_pB)
{
delete[]m_pB;
m_pB = NULL;
}
if (m_pShowDlg)
{
delete ((CShowImg*)m_pShowDlg);
m_pShowDlg = NULL;
}
m_bRGB = FALSE;
m_nHeight = 0;
m_nWidth = 0;
m_nPixelNum = 0;
}
CImage::~CImage()
{
Detroy();
}
CImage::Create(CSize szImg,BOOL bRGB)
{
Detroy();
if (szImg.cx<0||szImg.cy<0)
{
return FALSE;
}
m_bRGB = bRGB;
m_nHeight = szImg.cy;
m_nWidth = szImg.cx;
m_nPixelNum = szImg.cy*szImg.cx;
if (m_bRGB)
{
m_pR = new BYTE[m_nPixelNum];
m_pG = new BYTE[m_nPixelNum];
m_pB = new BYTE[m_nPixelNum];
if (m_pR==NULL||m_pG==NULL||m_pB==NULL)
{
Detroy();
return FALSE;
}
memset(m_pR,255,m_nPixelNum);
memset(m_pG,255,m_nPixelNum);
memset(m_pB,255,m_nPixelNum);
}
else
{
m_pR = new BYTE[m_nPixelNum];
if (m_pR==NULL)
{
Detroy();
return FALSE;
}
memset(m_pR,255,m_nPixelNum);
}
return TRUE;
}
BOOL CImage::Load(CString strPath)
{
CBitmap m_Bitmap;
BITMAP m_bm;
HANDLE hFile = ::CreateFile((LPCTSTR)strPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
return FALSE;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
ASSERT(-1 != dwFileSize);
LPVOID pvData = NULL;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
ASSERT( NULL != hGlobal);
pvData = GlobalLock(hGlobal);
ASSERT(NULL != pvData);
DWORD dwBytesRead = 0;
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
ASSERT(false != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
LPSTREAM pstm = NULL;
HRESULT hr = CreateStreamOnHGlobal(pvData, TRUE, &pstm);
ASSERT ( SUCCEEDED(hr) && pstm);
LPPICTURE gpPicture;
hr = ::OleLoadPicture(pstm, dwFileSize, true, IID_IPicture, (LPVOID*)&gpPicture);
ASSERT (SUCCEEDED(hr) && gpPicture);
pstm->Release();
OLE_HANDLE m_picHandle;
OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
gpPicture->get_Width(&hmWidth);
gpPicture->get_Height(&hmHeight);
gpPicture->get_Handle(&m_picHandle);
m_Bitmap.DeleteObject();
m_Bitmap.Attach((HGDIOBJ)m_picHandle);
m_Bitmap.GetBitmap(&m_bm);
//将从文件中读取的数据存入CImage类中。
int nWidth = m_bm.bmWidth;
int nHeight = m_bm.bmHeight;
int iLineBits = WIDTHBYTES(nWidth*m_bm.bmBitsPixel);
switch (m_bm.bmBitsPixel)
{
case 8:
{
if (!Create(CSize(nWidth,nHeight),FALSE))
{
return FALSE;
}
unsigned char* pTemp = (unsigned char*)m_bm.bmBits;
for (int i = 0; i<m_nHeight; i++)
{
pTemp = (BYTE*) (iLineBits*(nHeight-i-1)+(BYTE*)m_bm.bmBits);
memcpy(&m_pR[i*nWidth],pTemp,nWidth);
}
break;
}
case 16:
{
if (!Create(CSize(nWidth,nHeight),TRUE))
{
return FALSE;
}
WORD * pTemp = (WORD*)m_bm.bmBits;
double dRate = 255.0/31;
for (int i = nHeight-1; i>=0; i--)
{
pTemp = (WORD*)(iLineBits*(nHeight-i-1)+(BYTE*)m_bm.bmBits);
for(int j = 0; j<nWidth; j++)
{
m_pB[j+i*nWidth]=BYTE(dRate*((*pTemp)&0x1F));
m_pG[j+i*nWidth]=BYTE(dRate*((*pTemp>>5)&0x1F));
m_pR[j+i*nWidth]=BYTE(dRate*((*pTemp>>10)&0x1F));
pTemp++;
}
}
break;
}
case 24:
{
if (!Create(CSize(nWidth,nHeight),TRUE))
{
return FALSE;
}
unsigned char* pTemp = (unsigned char*)m_bm.bmBits;
for (int i = nHeight-1; i>=0; i--)
{
pTemp = (BYTE*) (iLineBits*(nHeight-i-1)+(BYTE*)m_bm.bmBits);
for(int j = 0; j<nWidth; j++)
{
m_pB[j+i*nWidth]=(*pTemp);
pTemp++;
m_pG[j+i*nWidth]=(*pTemp);
pTemp++;
m_pR[j+i*nWidth]=(*pTemp);
pTemp++;
}
}
}
break;
default:
return FALSE;
}
m_Bitmap.DeleteObject();
return TRUE;
}
BOOL CImage::Draw(CDC* pDC, CPoint origin, CSize size,BOOL bStretch,BOOL bCentre)
{
if (m_nHeight<=0||m_nWidth<=0)
{
return TRUE;
}
BITMAPINFOHEADER lpBMIH;
lpBMIH.biSize = sizeof(BITMAPINFOHEADER);
lpBMIH.biWidth = m_nWidth;
lpBMIH.biHeight = m_nHeight;
lpBMIH.biPlanes = 1;
lpBMIH.biBitCount = 24;
lpBMIH.biCompression = BI_RGB;
lpBMIH.biSizeImage = 0;
lpBMIH.biXPelsPerMeter = 0;
lpBMIH.biYPelsPerMeter = 0;
lpBMIH.biClrUsed = 0;
lpBMIH.biClrImportant = 0;
pDC->SetStretchBltMode(COLORONCOLOR);
int iLineBits = WIDTHBYTES(m_nWidth*24);
BYTE * lpImage = new BYTE[iLineBits*m_nHeight];
if (lpImage==NULL) {
return FALSE;
}
int lTargetIndex,lSourceIndex;
for(int i=0;i<m_nHeight;i++)
{
for(int j=0;j<m_nWidth;j++)
{
if (m_bRGB)
{
lTargetIndex=i*iLineBits+3*j;
lSourceIndex=m_nWidth*(m_nHeight-1-i)+j;
lpImage[lTargetIndex] = m_pB[lSourceIndex];
lpImage[lTargetIndex+1] = m_pG[lSourceIndex];
lpImage[lTargetIndex+2] = m_pR[lSourceIndex];
}
else
{
lTargetIndex=i*iLineBits+3*j;
lSourceIndex=m_nWidth*(m_nHeight-1-i)+j;
lpImage[lTargetIndex] = m_pR[lSourceIndex];
lpImage[lTargetIndex+1] = m_pR[lSourceIndex];
lpImage[lTargetIndex+2] = m_pR[lSourceIndex];
}
}
}
if (!bStretch)
{
CSize szOrg = size;
double dStreRate = min((double)size.cx/m_nWidth,(double)size.cy/m_nHeight);
size.cx = int(dStreRate*m_nWidth);
size.cy = int(dStreRate*m_nHeight);
if (bCentre)
{
CPoint ptOff;
ptOff.x = (szOrg.cx-size.cx)/2;
ptOff.y = (szOrg.cy-size.cy)/2;
origin += ptOff;
}
}
::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,
0, 0, lpBMIH.biWidth, lpBMIH.biHeight,
lpImage, (LPBITMAPINFO) &lpBMIH, DIB_RGB_COLORS, SRCCOPY);
delete []lpImage;
return TRUE;
}
//RGB转化为灰度图象,结果保存在ImgGray;
BOOL CImage::Rgb2Gray(CImage &ImgGray,double dR,double dG,double dB)
{
if (!m_bRGB)
{
return FALSE;
}
if (!ImgGray.Create(CSize(GetWidth(),GetHeight()),FALSE))
{
return FALSE;
}
int nPix = GetWidth()*GetHeight();
for(int i=0;i<nPix;i++)
{
ImgGray.m_pR[i] = BYTE(m_pR[i]*dR+m_pG[i]*dG+m_pB[i]*dB+0.5) ;
}
return TRUE;
}
//CSize szGrid模板大小
BOOL CImage::MaxMinGrid(CImage &ImgOut,CSize szGrid,double * pPara)
{
if (!ImgOut.Create(CSize(GetWidth(),GetHeight()),FALSE))
{
return FALSE;
}
int m,n;
m=(int)(szGrid.cx/2);
n=(int)(szGrid.cy/2);
int max_temp,min_temp;
int *temp=new int[szGrid.cx*szGrid.cy];
int i_temp;
for (int i=0;i<ImgOut.GetHeight();i++)
{
for (int j=0;j<ImgOut.GetWidth();j++)
{
max_temp=0;
min_temp=255;
i_temp=0;
for (int ii=i-m;ii<=i+m;ii++)
{
for (int jj=j-n;jj<=j+n;jj++)
{
if (ii>=0 && ii<m_nHeight && jj>=0 && jj<m_nWidth)
{
temp[i_temp]=int(m_pR[ii*m_nWidth+jj]);
i_temp=i_temp+1;
}
}
}
int temp1,temp2;
temp1=0;
temp2=0;
for (int k=0;k<i_temp;k++)
{
if (temp[k]>max_temp)
{
temp1=max_temp; //temp1为次大
max_temp=temp[k]; //max_temp为最大
}
else if ((temp[k]<min_temp))
{
temp2=min_temp; //temp2为次小
min_temp=temp[k]; //min_temp为最小
}
}
ImgOut.m_pR[i*m_nWidth+j]=BYTE((max_temp+min_temp)/2);
}
}
delete []temp;
return TRUE;
}
BOOL CImage::MaxMinMinusGrid(CImage &ImgOut, CSize szGrid, double *pPara)
{
if (!ImgOut.Create(CSize(this->GetWidth(),this->GetHeight()),FALSE))
{
return FALSE;
}
int m,n;
m=(int)(szGrid.cx/2);
n=(int)(szGrid.cy/2);
int max_temp,min_temp;
int *temp=new int[szGrid.cx*szGrid.cy];
int i_temp;
for (int i=0;i<ImgOut.GetHeight();i++)
{
for (int j=0;j<ImgOut.GetWidth();j++)
{
max_temp=0;
min_temp=255;
i_temp=0;
for (int ii=i-m;ii<=i+m;ii++)
{
for (int jj=j-n;jj<=j+n;jj++)
{
if (ii>=0 && ii<m_nHeight && jj>=0 && jj<m_nWidth)
{
temp[i_temp]=int(m_pR[ii*m_nWidth+jj]);
i_temp=i_temp+1;
}
}
}
int temp1,temp2;
temp1=0;
temp2=0;
for (int k=0;k<i_temp;k++)
{
if (temp[k]>max_temp)
{
temp1=max_temp; //temp1为次大
max_temp=temp[k]; //max_temp为最大
}
else if ((temp[k]<min_temp))
{
temp2=min_temp; //temp2为次小
min_temp=temp[k]; //min_temp为最小
}
}
ImgOut.m_pR[i*m_nWidth+j]=BYTE(max_temp-min_temp);
}
}
delete []temp;
return TRUE;
}
#include "ShowImg.h"
void CImage::ShowImg(HWND hWnd)
{
CShowImg ImgDlg(this,CWnd::FromHandle(hWnd));
ImgDlg.DoModal();
/* if (m_pShowDlg)
{
delete ((CShowImg*)m_pShowDlg);
m_pShowDlg = NULL;
}
CShowImg * pImgDlg = new CShowImg(this);
pImgDlg->Create(CShowImg::IDD);
pImgDlg->ShowWindow(SW_SHOW);
m_pShowDlg = pImgDlg;*/
}
//0不参与运算
BOOL CImage::CalculateSame(int * nData,int nNum,CList<CPoint,CPoint> &ptList,CPoint &ptMax)
{
if (nNum<1) {
return FALSE;
}
ptList.RemoveAll();
CPoint ptTemp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -