📄 image.cpp
字号:
POSITION posCurrent;
POSITION pos;
for(int i=0;i<nNum;i++)
{
pos = ptList.GetHeadPosition();
posCurrent = pos;
BOOL bAdd = FALSE;
while (pos)
{
ptTemp = ptList.GetNext(pos);
if (ptTemp.x==nData[i])
{
ptTemp.y++;
ptList.SetAt(posCurrent,ptTemp);
bAdd = TRUE;
break;
}
else if(ptTemp.x>nData[i])
{
ptTemp.x = nData[i];
ptTemp.y = 1;
ptList.InsertBefore(posCurrent,ptTemp);
bAdd = TRUE;
break;
}
posCurrent = pos;
}
if (!bAdd)
{
ptTemp.x = nData[i];
ptTemp.y = 1;
ptList.AddTail(ptTemp);
}
}
pos = ptList.GetHeadPosition();
ptMax = ptList.GetHead();
while (pos)
{
ptTemp = ptList.GetNext(pos);
if (ptMax.y<ptTemp.y)
{
ptMax = ptTemp;
}
}
return TRUE;
}
BOOL CImage::GetLineAB(CList<CPoint,CPoint> &ptList,double &dA,double &dB)
{
if (ptList.IsEmpty())
{
return FALSE;
}
long lCount=ptList.GetCount();
if (lCount<2)
{
return FALSE;
}
CPoint pFold;
double mX=0,mY=0,mXX=0,mXY=0;
double n;
n = lCount;
double *pEr = new double[lCount];
POSITION pos = ptList.GetHeadPosition();
while (pos!=NULL)
{
pFold = ptList.GetNext(pos);
mX+=pFold.x;
mY+=pFold.y;
mXX+=pFold.x*pFold.x;
mXY+=pFold.x*pFold.y;
}
if(mX*mX-mXX*n==0)
{
return FALSE;
}
dA=(mY*mX-mXY*n)/(mX*mX-mXX*n);
dB=(mY-mX*dA)/n;
for(int i=0;i<lCount;i++)
{
pFold = ptList.GetAt(ptList.FindIndex(i));
pEr[i] = (dA*pFold.x+dB - pFold.y)*(dA*pFold.x+dB - pFold.y);
}
delete []pEr;
return TRUE;
}
BOOL CImage::Filter(CImage &imgOut, int nNeighbor,BYTE nTextVal, BYTE nBGVal)
{
imgOut = *this;
int sum=0;
if (nNeighbor == 8)
{
for (int i=0;i<imgOut.GetHeight();i++)
{
for (int j=0;j<imgOut.GetWidth();j++)
{
sum=0;
for (int ii = i-1;ii<=i+1;ii++)
{
for (int jj=j-1;jj<=j+1;jj++)
{
if (ii == i && jj ==j)
{
continue;
}
else if (ii>=0 && ii<imgOut.GetHeight() && jj>=0 && jj<imgOut.GetWidth())
{
if (m_pR[ii*imgOut.GetWidth()+jj] == nTextVal)
{
sum = sum+1;
}
}
}
}
if (sum<2)
{
imgOut.m_pR[i*imgOut.GetWidth()+j] = nBGVal;
}
}
}
}
else
{
for (int i=0;i<imgOut.GetHeight();i++)
{
for (int j=0;j<imgOut.GetWidth();j++)
{
sum=0;
for (int ii = i-1;ii<=i+1;ii++)
{
for (int jj=j-1;jj<=j+1;jj++)
{
if (ii == i && jj ==j || ii != i && jj !=j)
{
continue;
}
else if (ii>=0 && ii<imgOut.GetHeight() && jj>=0 && jj<imgOut.GetWidth())
{
if (m_pR[ii*imgOut.GetWidth()+jj] == nTextVal)
{
sum = sum+1;
}
}
}
}
if (sum<2)
{
imgOut.m_pR[i*imgOut.GetWidth()+j] = nBGVal;
}
}
}
}
return TRUE;
}
BOOL CImage::AvgGrid(CImage &ImgOut,CSize szGrid,double * pPara)
{
if (!ImgOut.Create(CSize(this->GetWidth(),this->GetHeight()),FALSE))
{
return FALSE;
}
long int sum;
int sum1;
int m,n;
m=szGrid.cx/2;
n=szGrid.cy/2;
double dNum = szGrid.cx*szGrid.cy;
for (int i=0;i<ImgOut.GetHeight();i++)
{
for (int j=0;j<ImgOut.GetWidth();j++)
{
sum=0;
sum1=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 )
sum=sum+m_pR[ii*m_nWidth+jj];
else
sum1=sum1+1;
}
}
ImgOut.m_pR[i*ImgOut.GetWidth()+j]=BYTE(sum/(dNum-sum1));
}
}
return TRUE;
}
//以百分之多少作为域值,bReverse=FALSE时>dThreld*255时为255
BOOL CImage::Threthold(CImage &ImgOut,BYTE dThretd,BOOL bReverse)
{
if (!ImgOut.Create(CSize(m_nWidth,m_nHeight),FALSE))
{
return FALSE;
}
int nPix = m_nWidth*m_nHeight;
for(int i=0;i<nPix;i++)
{
if (bReverse)
{
ImgOut.m_pR[i] = (m_pR[i]>dThretd)?0:255;
}
else
{
ImgOut.m_pR[i] = m_pR[i]>dThretd?255:0;
}
}
return TRUE;
}
BOOL CImage::GetChePaiRect(CImage &ImgOut,CImage &ImgGray,CList<CRect,CRect>& rcChePaiList)
{
rcChePaiList.RemoveAll();
if (!ImgOut.Create(CSize(m_nWidth,m_nHeight),FALSE))
{
return FALSE;
}
BOOL bSuceed = FALSE;
int *pR = new int[m_nHeight];
int *pSum = new int[m_nWidth];
if ((!pR)||(!pSum)) {
return FALSE;
}
memset(pR,0,sizeof(int)*m_nHeight);
memset(pSum,0,sizeof(int)*m_nWidth);
for(int i=0;i<m_nHeight;i++)
{
int nStart = 0;
int nEnd = 0;
int nRepeate = 0;
int temp = 0;
int start = 0;
for(int k=0;k<m_nWidth-1;k++)
{
if (start==0 && m_pR[i*m_nWidth+k]==255)
{
nStart = k;
nEnd = k;
nRepeate = 1;
start = 1;
}
else if (start==1 && k-nEnd<4 && m_pR[i*m_nWidth+k]==255)
{
nEnd = k;
nRepeate ++;
}
else if (start==1 && k-nEnd>=4)
{
if (nRepeate<8)
{
start = 0;
}
else
{
if (nRepeate>temp)
{
temp = nRepeate;
pR[i] = nRepeate;
}
start = 0;
}
}
}
}
//TRACE(GetIntToString(pR,m_nHeight));
int nStart = 0;
int nEnd = 0;
int start=0;
CList<CPoint,CPoint> ptList;
int nC = 0;
int nD = 0;
int nK = 1;
int nL = 0;
while (nL<m_nHeight-1)
{
if (pR[nL]>=8 && pR[nL]<40)
{
nC++;
nD = 0;
}
else
{
nD++;
}
if (nC<5&&nD>2)
{
nD = 0;
nC = 0;
}
else if ((nD>2&&nC>=5)||(nC+nD)>5)
{
for (int k=nL;k<nL+3;k++)
{
if (k>m_nHeight-1)
{
k=m_nHeight-1;
break;
}
if (pR[k]<8 && pR[k]>40)
{
break;
}
}
ptList.AddTail(CPoint(nL-nC-nD,k));
nL=k;
nD = 0;
nC = 0;
}
nL++;
}
POSITION pos = ptList.GetHeadPosition();
if (pos==NULL)
{
delete []pR;
delete []pSum;
return FALSE;
}
CRect rcLast(0,0,0,0);
while (pos)
{
memset(pSum,0,sizeof(int)*m_nWidth);
CPoint ptSE = ptList.GetNext(pos);
nStart = max(ptSE.x-5,0);
nEnd = min(ptSE.y+5,m_nHeight);
int nStart1 =0,nEnd1=0,cishu=1;
for(i=nStart;i<nEnd;i++)
{
for(int j=0;j<m_nWidth-1;j++)
{
if (m_pR[i*m_nWidth+j]==255)
{
pSum[j] += 1;
}
}
}
// TRACE(GetIntToString(pSum,m_nWidth/2));
// TRACE(GetIntToString(pSum+m_nWidth/2,m_nWidth/2));
nD = 0;
nC = 0;
nStart = 0;
nEnd = 0;
start=0;
for(int i=0;i<m_nWidth-1;i++)
{
if (pSum[i]>=3 && start==0)
{
nStart = i;
nD = 0;
start = 1;
nC = 1;
}
else if (pSum[i]>=3 && start==1)
{
nD = 0;
nC ++;
}
else if (pSum[i]<3 && start==1)
{
nD++;
}
if (nD>6 && start==1 && nC<=20)
{
start = 0;
nC = 0;
nD = 0;
}
else if (nD>6 && start==1 && nC>20)
{
nEnd = i;
if (nStart<15)
{
start = 0;
nStart = i;
}
else if(cishu==1)
{
nStart1 = nStart;
nEnd1 = nEnd;
cishu++;
start =0;
nStart = i;
}
else
{
break;
}
}
else if (nD<=6 && nC>20 && i>=m_nWidth-2)
{
nEnd = i;
if (nStart<15)
{
start = 0;
nStart = i;
}
else
{
break;
}
}
}
if ((nEnd1-nStart1)>(nEnd-nStart))
{
nStart = nStart1;
nEnd = nEnd1;
}
if (nStart<nEnd)
{
CRect rcTemp,rcTemp1,rcTemp2,rcTemp3,rcTemp4;
CRect rcOut(0,0,0,0);
rcTemp.top = max(ptSE.x-5,0);
rcTemp.bottom = min(ptSE.y+10,m_nHeight);
rcTemp.left = max(nStart-5,0);
rcTemp.right = min(nEnd,m_nWidth);
rcTemp2.top = max(ptSE.x,0);
rcTemp2.bottom = min(ptSE.y+5,m_nHeight);
rcTemp2.left = max(nStart,0);
rcTemp2.right = min(nEnd,m_nWidth);
rcTemp4.top = min(ptSE.y+11,m_nHeight);
rcTemp4.bottom = min(ptSE.y+13,m_nHeight);
rcTemp4.left = max(nStart,0);
rcTemp4.right = min(nEnd,m_nWidth);
BOOL IsChePai = TRUE;
int dis = rcTemp4.right-rcTemp4.left+1;
int *nX = new int[3];
int *nY = new int[dis];
memset(nX,0,sizeof(int)*3);
memset(nY,0,sizeof(int)*dis);
if (GetOvlap(rcOut,rcTemp,rcLast))//有重叠
{
CRect rcTT = rcTemp;
if (rcOut.Width()>1&&rcOut.Height()>1) //要合并
{
rcTemp.top = min(rcTemp.top,rcLast.top);
rcTemp.left = min(rcTemp.left,rcLast.left);
rcTemp.right = max(rcTemp.right,rcLast.right);
rcTemp.bottom = max(rcTemp.bottom,rcLast.bottom);
}
if (rcTemp.Width()>120||rcTemp.Height()>45)
{
rcTemp = rcTT;
}
}
rcLast = rcTemp;
int nAvg =0 ,nS =0;
GetAvgandS(nAvg,nS,rcTemp2);
if (rcTemp.bottom == m_nHeight || rcTemp.bottom == m_nHeight-1)
{
rcTemp3.top = min(ptSE.x-11,m_nHeight);
rcTemp3.bottom = min(ptSE.x-9,m_nHeight);
rcTemp3.left = max(nStart,0);
rcTemp3.right = min(nEnd,m_nWidth);
GetTextPointNum(nX,nY,rcTemp3,255);
for (i=0; i<2;i++)
{
if (nX[i]>=0.2*nAvg)
{
IsChePai = FALSE;
break;
}
}
}
memset(nX,0,sizeof(int)*3);
memset(nY,0,sizeof(int)*dis);
GetTextPointNum(nX,nY,rcTemp4,255);
for (i=0 ; i<2;i++)
{
if (nX[i]>=0.8*nAvg)
{
IsChePai = FALSE;
break;
}
}
double dR;
dR=(double)rcTemp.Width()/rcTemp.Height();
if (dR>1.5 && dR<5 && rcTemp.Width()>45 && nAvg>=18 && IsChePai && rcTemp.Height()<35)
{
for(i=rcTemp.top;i<rcTemp.bottom;i++)
{
for(int j=rcTemp.left;j<rcTemp.right;j++)
{
ImgOut.m_pR[i*m_nWidth+j] = ImgGray.m_pR[i*m_nWidth+j];
}
}
bSuceed = TRUE;
rcChePaiList.AddTail(rcTemp);
}
delete []nX;
delete []nY;
}
}
delete []pR;
delete []pSum;
return bSuceed;
}
BOOL CImage::GetTiaoBian(int *nTiaoBianX, int *nTiaoBianY,CRect rcR)
{
if (rcR.IsRectEmpty())
{
return FALSE;
}
for(int i=rcR.top;i<rcR.bottom;i++)
{
for(int j=rcR.left;j<rcR.right-1;j++)
{
if (m_pR[i*m_nWidth+j]!=m_pR[i*m_nWidth+j+1])
{
nTiaoBianX[i-rcR.top]++;
}
}
}
for(i=rcR.left;i<rcR.right;i++)
{
for(int j=rcR.top;j<rcR.bottom-1;j++)
{
if (m_pR[i+j*m_nWidth]!=m_pR[i+1+j*m_nWidth])
{
nTiaoBianY[i-rcR.left]++;
}
}
}
return TRUE;
}
//从原图剪切出一个区域
BOOL CImage::CutFromImg(CImage &ImgOut,CRect rcImg)
{
if (rcImg.left<0||rcImg.top<0||rcImg.right>m_nWidth||rcImg.bottom>m_nHeight)
{
return FALSE;
}
if (!ImgOut.Create(CSize(rcImg.Width(),rcImg.Height()),this->IsRGB()))
{
return FALSE;
}
for(int i=0;i<rcImg.Height();i++)
{
memcpy(ImgOut.m_pR+i*rcImg.Width(),m_pR+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
if (m_bRGB)
{
memcpy(ImgOut.m_pG+i*rcImg.Width(),m_pG+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
memcpy(ImgOut.m_pB+i*rcImg.Width(),m_pB+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
}
}
return TRUE;
}
//细定位
/*
* 水平方向的截取是根据跳变
* 竖直方向是根据黑点个数
* 去头去未是根据最大连续点个数
*/
BOOL CImage::CutExact(CImage &ImgOut)
{
CImage ImgTemp;
CRect rcReal;
int *nX = new int[m_nWidth];
int *nTiaoBianY = new int[m_nHeight];
memset(nTiaoBianY,0,sizeof(int)*m_nHeight);
memset(nX,0,sizeof(int)*m_nWidth);
//先去左右边界
int i;
rcReal.left = 0;
rcReal.right = m_nWidth;
rcReal.top = 0;
rcReal.bottom = m_nHeight;
//黑点个数,垂直方向
for (i=0;i<m_nWidth;i++)
{
for (int j=0;j<m_nHeight;j++)
{
if(m_pR[j*m_nWidth+i]==0)
{
nX[i]++;
}
}
}
for (i=0;i<m_nWidth/5;i++)
{
if(nX[i]>0.80*m_nHeight && nX[i+1]<0.2*m_nHeight)
{
continue;
}
else
{
rcReal.left = i;
break;
}
}
//去掉上下边界
//跳变个数,水平方向
for(i=0;i<m_nHeight;i++)
{
for(int j=0;j<m_nWidth-1;j++)
{
if (m_pR[i*m_nWidth+j]!=m_pR[i*m_nWidth+1+j])
{
nTiaoBianY[i]++;
}
}
}
// TRACE(GetIntToString(nTiaoBianY,m_nHeight));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -