通用的字符分割源代码

void FFTGabor::GaborTransform(int * lpDIBBits, LONG lWidth, LONG lHeight, int Orientation, int Frequency, FFTGaborResult * result)
{
        LONG        i;
        LONG        j;

        complex<double> *TD = new complex<double>[complexWidth * complexHeight];
        complex<double> *FD = new complex<double>[complexWidth * complexHeight];
        
        // 行
        for(i = 0; i < lHeight; i++) 
        {
                // 列
                for(j = 0; j < lWidth; j++)
                {
                        // 给时域赋值
                        TD[j + complexWidth * i] = complex<double>(lpDIBBits[j+lWidth * i], 0);
                }
        }
        ::FFT2(TD,complexWidth , complexHeight);
        
        //::IFFT2(TD,256,256);
        //在频域执行卷积
        double scale = 1.0 / (complexWidth * complexHeight); 
        
        for( i=0; i<complexWidth * complexHeight; i++)
                FD[i] = TD[i] * KernelFFT2[Orientation * 4 + Frequency][i] ; // * scale; 
        
        IFFT2(FD,complexWidth , complexHeight);
        
        //计算均值、方差及结果
        //计算均值并找出tmpMag中的最大最小值,以便调整到0~255,用于显示输出。
        double min, max;
        double Sum=0, Avg=0, Deta=0;
        double tmpModulus=0;
        double * tmpMag = new double[lWidth*lHeight] ;// [128][128] ;
        int x ,y;
        tmpModulus = sqrt(FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].real() *
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].real() +
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].imag() *
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].imag());
        min = max = tmpModulus;
        for( y=(GaborHeight/2); y<(GaborHeight/2)+lHeight; y++){
                for( x=(GaborWidth/2); x<(GaborWidth/2)+lWidth; x++)
                {
                        tmpModulus = sqrt(FD[y*complexWidth+x].real() * FD[y*complexWidth+x].real() +
                                FD[y*complexWidth+x].imag() * FD[y*complexWidth+x].imag());
                        
                        if(min>tmpModulus)
                                min = tmpModulus;
                        if(max<tmpModulus)
                                max = tmpModulus;        
                        
                        Sum += tmpModulus;
                        tmpMag[(y-(GaborHeight/2))* lWidth + (x-(GaborWidth/2))] = tmpModulus;
                }
        }
        Avg = Sum / (lHeight * lWidth);
        //计算方差
        for( y=0; y < lHeight; y++){
                for( x=0; x < lWidth; x++)
                        Deta += (tmpMag[y* lWidth + x] - Avg)*(tmpMag[y* lWidth + x] - Avg);
        }
        Deta = Deta / (lHeight * lWidth);
        
        //计算magShow以及均值
        scale = 255.0/(max-min);
        
        for( y=0; y < lHeight; y++){
                for( x=0; x < lWidth; x++)
                {
                        result->magShow[y * lWidth + x] = (int)(scale*(tmpMag[y* lWidth + x]-min));
                }
        }
        result->Avg = Avg;
        result->Deta = Deta;
        
        delete[] tmpMag;

        delete[] FD;
        delete[] TD;
}

void FFTGabor::intTocomplex(complex<double> * TD,int * lpDIBBits,LONG lWidth, LONG lHeight)
{
        LONG        i;
        LONG        j;

//        complex<double> *TD = new complex<double>[complexWidth * complexHeight];
        
        // 行
        for(i = 0; i < lHeight; i++) 
        {
                // 列
                for(j = 0; j < lWidth; j++)
                {
                        // 给时域赋值
                        TD[j + complexWidth * i] = complex<double>(lpDIBBits[j+lWidth * i], 0);
                }
        }
        ::FFT2(TD,complexWidth , complexHeight);

}
void FFTGabor::GaborTransform(complex<double> *TD, LONG lWidth, LONG lHeight, double * TransformResult)
{
        // 循环变量
        LONG        i;
//        LONG        j;
        int Orientation, Frequency ;
        // 分配内存
        complex<double> *FD = new complex<double>[complexWidth * complexHeight];
        
        double scale = 1.0 / (complexWidth * complexHeight); 
        double Sum=0, Avg=0, Deta=0;
        double tmpModulus=0;
        double * tmpMag = new double[lWidth*lHeight] ;// [128][128] ;
        int x ,y;
        
        for( Orientation=0; Orientation<8; Orientation++){
                for( Frequency=0; Frequency<4; Frequency++)
                {
                        //在频域执行卷积
                        for( i=0; i<complexWidth * complexHeight; i++)
                                FD[i] = TD[i] * KernelFFT2[Orientation * 4 + Frequency][i] ; // * scale; 
                        
                        IFFT2(FD,complexWidth , complexHeight);
                        
                        //计算均值、方差及结果
                        Sum=0, Avg=0, Deta=0;
                        
                        for( y=(GaborHeight/2); y<(GaborHeight/2)+lHeight; y++){
                                for( x=(GaborWidth/2); x<(GaborWidth/2)+lWidth; x++)
                                {
                                        tmpModulus = sqrt(FD[y*complexWidth+x].real() * FD[y*complexWidth+x].real() +
                                                FD[y*complexWidth+x].imag() * FD[y*complexWidth+x].imag());
                                        
                                        Sum += tmpModulus;
                                        tmpMag[(y-(GaborHeight/2)) * lWidth + (x-(GaborWidth/2))] = tmpModulus;
                                }
                        }
                        Avg = Sum / (lHeight * lWidth);
                        //计算方差
                        for( y=0; y < lHeight; y++){
                                for( x=0; x < lWidth; x++)
                                        Deta += (tmpMag[y* lWidth + x] - Avg)*(tmpMag[y* lWidth + x] - Avg);
                        }
                        Deta = Deta / (lHeight * lWidth);
                        

                        TransformResult[(Orientation * 4 + Frequency)*2] = Avg;
                        TransformResult[(Orientation * 4 + Frequency)*2+1] = Deta;
                }
        }
        
        delete[] tmpMag;
        delete[] FD;
}

void FFTGabor::GaborTransform(complex<double> *TD, LONG lWidth, LONG lHeight, int Orientation, int Frequency, FFTGaborResult * result)
{
        LONG        i;
//        LONG        j;

        complex<double> *FD = new complex<double>[complexWidth * complexHeight];
        

        //在频域执行卷积
        double scale = 1.0 / (complexWidth * complexHeight); 
        
        for( i=0; i<complexWidth * complexHeight; i++)
                FD[i] = TD[i] * KernelFFT2[Orientation * 4 + Frequency][i] ; // * scale; 
        
        IFFT2(FD,complexWidth , complexHeight);
        
        //计算均值、方差及结果
        //计算均值并找出tmpMag中的最大最小值,以便调整到0~255,用于显示输出。
        double min, max;
        double Sum=0, Avg=0, Deta=0;
        double tmpModulus=0;
        double * tmpMag = new double[lWidth*lHeight] ;// [128][128] ;
        int x ,y;
        tmpModulus = sqrt(FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].real() *
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].real() +
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].imag() *
                                                                FD[(GaborHeight/2)*complexWidth+(GaborWidth/2)].imag());
        min = max = tmpModulus;
        for( y=(GaborHeight/2); y<(GaborHeight/2)+lHeight; y++){
                for( x=(GaborWidth/2); x<(GaborWidth/2)+lWidth; x++)
                {
                        tmpModulus = sqrt(FD[y*complexWidth+x].real() * FD[y*complexWidth+x].real() +
                                FD[y*complexWidth+x].imag() * FD[y*complexWidth+x].imag());
                        
                        if(min>tmpModulus)
                                min = tmpModulus;
                        if(max<tmpModulus)
                                max = tmpModulus;        
                        
                        Sum += tmpModulus;
                        tmpMag[(y-(GaborHeight/2))* lWidth + (x-(GaborWidth/2))] = tmpModulus;
                }
        }
        Avg = Sum / (lHeight * lWidth);
        //计算方差
        for( y=0; y < lHeight; y++){
                for( x=0; x < lWidth; x++)
                        Deta += (tmpMag[y* lWidth + x] - Avg)*(tmpMag[y* lWidth + x] - Avg);
        }
        Deta = Deta / (lHeight * lWidth);
        
        //计算magShow以及均值
        scale = 255.0/(max-min);
        
        for( y=0; y < lHeight; y++){
                for( x=0; x < lWidth; x++)
                {
                        result->magShow[y * lWidth + x] = (int)(scale*(tmpMag[y* lWidth + x]-min));
                }
        }
        result->Avg = Avg;
        result->Deta = Deta;
        
        delete[] tmpMag;

        delete[] FD;
}


///车牌字符分割

void CSegmentationView::PlateSegm(BYTE Rt[][MAXWIDTH],BYTE Gt[][MAXWIDTH],BYTE Bt[][MAXWIDTH],int PlateHeight,int PlateWidth)
{
        CDC *pDC=GetDC();
    int i,j;
        BYTE TotalRGB[230][460];
        memset(TotalRGB,0,sizeof(BYTE)*230*460);
        int *HistH;
        HistH=new int[sizeof(int)*PlateHeight];
        memset(HistH,0,sizeof(int)*PlateHeight);
// 显示车牌图像并水平投影
        for(i=0;i<PlateHeight;i++)
        {                for(j=0;j<PlateWidth;j++)
                        {
                            pDC->SetPixel(450+j,100+i,RGB(Rt[i][j],Gt[i][j],Bt[i][j]));
                                TotalRGB[i][j]=Rt[i][j]+Gt[i][j]+Bt[i][j];
                
                                if(Bt[i][j]>Gt[i][j]&&Bt[i][j]>Rt[i][j]&&(Bt[i][j]/(float)TotalRGB[i][j])>0.4)
                                        HistH[i]++;
                        }
                    pDC->MoveTo(800,100+i);
                        pDC->LineTo(800+HistH[i],100+i);
        }
//显示宽度除以10.0的长度
        pDC->MoveTo(800,50);
        pDC->LineTo(800+PlateWidth/10.0,50);
        
//求水平边界
        int flag=1;

        for(i=PlateHeight/2;i>=0;i--)
        {
                if(HistH[i]>0)
                {
                        if(flag)
                        {
                                flag=0;
                        }
                        else
                        {
                            PlateRect.top=i;
                                if(HistH[i]<PlateWidth/10.0)
                               break;
                                
                        }
                }
                else if(HistH[i]==0)
                         break;
        
                
        }

        flag=1;
        for(i=PlateHeight/2;i<PlateHeight;i++)
        {
                if(HistH[i]>0)
                {
                        if(flag)
                        {
                                flag=0;
                        }
                        else
                        {
                                PlateRect.bottom=i;
                                if(HistH[i]<PlateWidth/10.0)
                               break;
                                
                        }
                }
                else if(HistH[i]==0)
                         break;
                                
        }
        delete []HistH;HistH=NULL;
   // PlateHeight=bottom-top+1;

        //垂直投影
        int *HistV;
        HistV=new int[sizeof(int)*PlateWidth];
        memset(HistV,0,sizeof(int)*PlateWidth);
                
        for(i=0;i<PlateWidth;i++)
        {        for(j=PlateRect.top;j<=PlateRect.bottom;j++)
                {
                   
                         if(Bt[j][i]>Gt[j][i] &&Bt[j][i]>Rt[j][i]&&(Bt[j][i]/(float)TotalRGB[j][i])>0.4)
                                        HistV[i]++;
                }
                pDC->MoveTo(450+i,100);                              
                    pDC->LineTo(450+i,100-HistV[i]);
        }

        //显示高度除以8.0的长度
//        pDC->MoveTo(400,50);
//        pDC->LineTo(400,50-PlateHeight/8.0);
//        int left,right;

         flag=1;
        for(i=PlateWidth/2;i>=0;i--)
        {
                if(HistV[i]>0)
                {
                        if(flag)
                        {
                                flag=0;
                        }
                        else
                        {
                                PlateRect.left=i;
                        }
                }
                else if(HistV[i]==0)
                         break;                
        }

        flag=1;
        for(i=PlateWidth/2;i<PlateWidth;i++)
        {
                if(HistV[i]>0)
                {
                        if(flag)
                        {
                                flag=0;
                        }
                        else
                        {
                                PlateRect.right=i;
        
                        }
                }
                else if(HistV[i]==0)
                         break;        
        }

        delete []HistV;HistV=NULL;


    CString str;
        pDC->TextOut(0,180,"缩小范围:");
        str.Format("高=%d",PlateRect.bottom-PlateRect.top+1);
        pDC->TextOut(0,200,str);
        str.Format("宽=%d",PlateRect.right-PlateRect.left+1);
        pDC->TextOut(0,220,str);

           BYTE PlateGray[230][460];
        memset(PlateGray,0,sizeof(BYTE)*230*460);
   
   //灰度化
                for(i=PlateRect.top;i<=PlateRect.bottom;i++)
                        for(j=PlateRect.left;j<=PlateRect.right;j++)
                {
                        PlateGray[i][j]=(Rt[i][j]+Gt[i][j]+Bt[i][j])/3;
                
                        
                }

        
//2显示灰度图像
                for(i=PlateRect.top;i<=PlateRect.bottom;i++)
                        for(j=PlateRect.left;j<=PlateRect.right;j++)
                        {
                                pDC->SetPixel(50+j,200+i,RGB(PlateGray[i][j],PlateGray[i][j],PlateGray[i][j]));
                        }

                //plateThre
           BYTE Data;
                   int Thre=OstuThroldDIB3Out(PlateGray);
         

                           for(i=PlateRect.top;i<=PlateRect.bottom;i++)
                            for(j=PlateRect.left;j<=PlateRect.right;j++)
                                  {
                                          if(PlateGray[i][j]<Thre)
                                          {
                                                 Data=255;

                                          }
                                          else            
                                          {                
                                                  Data=0;
                                          }

         //3显示车牌区域二值化后的图像
                      pDC->SetPixel(50+j,300+i,RGB(Data,Data,Data));
                                  }
            

                           /*------------------------------------------------------
                            
                                     次 函数调用代码添加处

                           -------------------------------------------------------*/
                     StrongObject3Out(PlateGray);//对车牌区域直方图均衡化
                         Thre=OstuThroldDIB3Out(PlateGray);

                            for(i=PlateRect.top;i<=PlateRect.bottom;i++)
                                {
                                     for(j=PlateRect.left;j<=PlateRect.right;j++)
                                         {  
//4显示直方图均衡化的图像
                                                 pDC->SetPixel(50+j,400+i,RGB(PlateGray[i][j],PlateGray[i][j],PlateGray[i][j]));
                                                
                                                 // 对直方图均衡化后的车牌区域再次二值化
                                                if(PlateGray[i][j]<Thre)
                                                 {
                                                         PlateGray[i][j]=255;
                                                         
                                                 }
                                                 else
                                                 {
                                                         PlateGray[i][j]=0;
                                                 }

//5显示二值化的图像
                                                 pDC->SetPixel(50+j,500+i,RGB(PlateGray[i][j],PlateGray[i][j],PlateGray[i][j]));
                                         }
                                 }
                                CPen GreenPen(PS_SOLID,1,RGB(0,255,0));
                                CPen *OldPen;
                    OldPen=pDC->SelectObject(&GreenPen);
                pDC->SelectStockObject(NULL_BRUSH);
                    pDC->Rectangle(50+PlateRect.left,500+PlateRect.top,50+PlateRect.right,500+PlateRect.bottom);



                                         /**--------------------------------------------------
                       
                      调用函数PlateProjection, 对车牌区域的上下边界进行再定位,
                      对车牌区域进行垂直方向的投影,分割出各个单个的字符位置

                     -----------------------------------------------------**/               
    
                                    PlateProjection(PlateGray,PlateHeight,PlateWidth);   
           
         //
        pDC->SelectObject(OldPen);
        ReleaseDC(pDC);

}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值