从上到下在内存中寻找黑白交接点,很简单的,只要查找每条线上各个像素的值,发现结果突然接近0的时候就是你要找的Y坐标.
另外:BMP的原点(0, 0)是在图片的左下方。

解决方案 »

  1.   

    在这里不是很容易说清楚,因为涉及到图片的色深和Width.如果你会Load位图,能够得到象素位的指针,我可以教你怎样算,否则就比较麻烦。你也可以参考<<Windows程序设计>>第十五章“与设备无关的位图”,
      

  2.   

    位图的格式我已经很清楚了。我可以得到那条直线的RGB值了,并且可以转化为灰度值(0-255)。
      

  3.   

    #include "stdafx.h"
    #include "dibapi.h"
    #include <io.h>
    #include <errno.h>#include <math.h>
    #include <direct.h>#define PI 3.1415926535
    //*Dib文件头标志(写字符"BM",写DIB时用到该常数)
    #define DIB_HEADER_MARKER ((WORD)('M'<<8)|'B')BOOL  WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette *pPal)
    {
    LPSTR lpDIBHdr;
    LPSTR lpDIBBits;
    BOOL bSuccess=FALSE;
    HPALETTE hPal=NULL;
    HPALETTE hOldPal;
    if(hDIB==NULL)
    return FALSE;
    lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
    lpDIBBits=::FindDIBBits(lpDIBHdr);
    if(pPal!=NULL)
    {
    hPal=(HPALETTE)pPal->m_hObject;
    hOldPal=::SelectPalette(hDC,hPal,TRUE);
    }
    ::SetStretchBltMode(hDC,COLORONCOLOR);
    if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
    {
    bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,
                             RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),
     lpDIBRect->left,(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
     0,(WORD)DIBHeight(lpDIBHdr),lpDIBBits,
     (LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
    }
    else
    {
    bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,
                         RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),
     lpDIBRect->left,lpDIBRect->top,
     RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),
     lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
    }
    ::GlobalUnlock((HGLOBAL)hDIB);
    if(hOldPal!=NULL)
    {
    ::SelectPalette(hDC,hOldPal,TRUE);
    }
    return bSuccess;
    }
    BOOL  WINAPI CreateDIBPalette(HDIB hDIB,CPalette *cPal)
    {
    LPLOGPALETTE lpPal;
    HANDLE hLogPal;
    HPALETTE hPal=NULL;
    int i;
    WORD wNumColors;
    LPSTR lpbi;
    LPBITMAPINFO lpbmi;
    LPBITMAPCOREINFO lpbmc;
    BOOL bWinStyleDIB;
    BOOL bResult=FALSE;
    if(hDIB==NULL)
    return FALSE;
    lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
    lpbmi=(LPBITMAPINFO)lpbi;
    lpbmc=(LPBITMAPCOREINFO)lpbi;
    wNumColors=::DIBNumColors(lpbi);
    if(wNumColors!=0)
    {
    hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
    if(hLogPal==0)
    {
    ::GlobalUnlock((HGLOBAL)hDIB);
    return FALSE;
    }
    lpPal=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
    lpPal->palVersion=PALVERSION;
    lpPal->palNumEntries=(WORD)wNumColors;
    bWinStyleDIB=IS_WIN30_DIB(lpbi);
    for(i=0;i<(int)wNumColors;i++)
    {
    if(bWinStyleDIB)
    {
    lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
    lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
    lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
    lpPal->palPalEntry[i].peFlags=0;
    }
    else
    {
    lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
    lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
    lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
    lpPal->palPalEntry[i].peFlags=0;
    } }
    bResult=cPal->CreatePalette(lpPal);
    ::GlobalUnlock((HGLOBAL)hLogPal);
    ::GlobalFree((HGLOBAL)hLogPal); }
    ::GlobalUnlock((HGLOBAL)hDIB);
    return bResult;
    }
    LPSTR WINAPI FindDIBBits(LPSTR lpbi)
    {
    return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));
    }
    DWORD WINAPI DIBWidth(LPSTR lpDIB)
    {
    LPBITMAPINFOHEADER lpbmi;
    LPBITMAPCOREHEADER lpbmc; lpbmi=(LPBITMAPINFOHEADER)lpDIB;
    lpbmc=(LPBITMAPCOREHEADER)lpDIB;
    if(IS_WIN30_DIB(lpDIB))
      return lpbmi->biWidth;
    else
    return (DWORD)lpbmc->bcWidth;
    }
    DWORD WINAPI DIBHeight(LPSTR lpDIB)
    {
    LPBITMAPINFOHEADER lpbmi;
    LPBITMAPCOREHEADER lpbmc; lpbmi=(LPBITMAPINFOHEADER)lpDIB;
    lpbmc=(LPBITMAPCOREHEADER)lpDIB;
    if(IS_WIN30_DIB(lpDIB))
      return lpbmi->biHeight;
    else
    return (DWORD)lpbmc->bcHeight;}
    WORD  WINAPI PaletteSize(LPSTR lpbi)
    {
    if(IS_WIN30_DIB(lpbi))
    {
    return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBQUAD));
    }
    else
    return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
    }
    WORD  WINAPI DIBNumColors(LPSTR lpbi)
    {
    WORD wBitCount;
    if(IS_WIN30_DIB(lpbi))
    {
    DWORD dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
    if(dwClrUsed!=0)
    return (WORD)dwClrUsed;
    }
    if(IS_WIN30_DIB(lpbi))
    {
    wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
    }
    else
    {
    wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
    }
    switch(wBitCount)
    {
    case 1:
    return 2;
    case 4:
    return 16;
    case 8:
    return 256;
    default:
    return 0; }

    }
    HGLOBAL WINAPI CopyHandle(HGLOBAL h)
    {
    if(h==NULL)
    return NULL;
    DWORD dwLen=::GlobalSize((HGLOBAL)h);
    HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);
    if(hCopy!=NULL)
    {
    void *lpCopy=::GlobalLock((HGLOBAL)hCopy);
    void *lp=::GlobalLock((HGLOBAL)h);
    memcpy(lpCopy,lp,dwLen);
    ::GlobalUnlock(hCopy);
    ::GlobalUnlock(h);
    }
    return hCopy;
    }
    BOOL WINAPI SaveDIB(HDIB hDib,CFile &file)
    {
    BITMAPFILEHEADER bmfHdr;
    LPBITMAPINFOHEADER lpBI;
    DWORD dwDIBSize;
    if(hDib==NULL)
    {
    return FALSE;
    }
    lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
    if(lpBI==NULL)
    return FALSE;
    if(!IS_WIN30_DIB(lpBI))
    {
    ::GlobalUnlock((HGLOBAL)hDib);
    return FALSE;
    }
    bmfHdr.bfType=DIB_HEADER_MARKER;
    dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
    if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
    dwDIBSize+=lpBI->biSizeImage;
    else
    {
    DWORD dwBmBitsSize;
    dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
    dwDIBSize+=dwBmBitsSize;
    lpBI->biSizeImage=dwBmBitsSize;
    }
    bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
    bmfHdr.bfReserved1=0;
    bmfHdr.bfReserved2=0;
    bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+PaletteSize((LPSTR)lpBI);
    TRY
    {
    file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
    file.WriteHuge(lpBI,dwDIBSize);
    }
    CATCH(CFileException,e)
    {
    ::GlobalUnlock((HGLOBAL)hDib);
    THROW_LAST();
    }
    END_CATCH
    ::GlobalUnlock((HGLOBAL)hDib);
        return TRUE;

    }
    HDIB WINAPI ReadDIBFile(CFile &file)
    {
       BITMAPFILEHEADER bmfHeader;
       DWORD dwBitsSize;
       HDIB hDIB;
       LPSTR pDIB;
       dwBitsSize=file.GetLength();
       if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
       return NULL;
       if(bmfHeader.bfType!=DIB_HEADER_MARKER)
       {
       return NULL;
       }
       hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
       if(hDIB==0)
       return NULL;
       pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
       if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
       {
       ::GlobalUnlock((HGLOBAL)hDIB);
       ::GlobalFree((HGLOBAL)hDIB);
       return NULL;
       }
       ::GlobalUnlock((HGLOBAL)hDIB);
       return hDIB;
    }
      

  4.   

    //=======================离散余弦变换==========================
    VOID WINAPI DCT(double *f,double *F,int r)
    {
    long count=1<<r;
       int i;
       double dTemp;
       complex<double>*X;
       X=new complex<double>[count*2];
       memset(X,0,sizeof(complex<double>)*count*2);
       for(i=0;i<count;i++)
       X[i]=complex<double>(f[i],0);
       FFT(X,X,r+1);
       dTemp=1/sqrt(count);
       F[0]=X[0].real()*dTemp;
       dTemp*=sqrt(2);
       for(i=1;i<count;i++)
       {
         F[i]=(X[i].real()*cos(i*PI/(count*2))+X[i].imag()*sin(i*PI/(count*2)))*dTemp;
       }
       delete X;
    }
    VOID WINAPI IDCT(double *F,double *f,int r)
    {
    long count=1<<r;
       int i;
       double dTemp,d0;
       complex<double>*X;
       X=new complex<double>[count*2];
       memset(X,0,sizeof(complex<double>)*count*2);
       for(i=0;i<count;i++)
       X[i]=complex<double>(F[i]*cos(i*PI/(count*2)),F[i]*sin(i*PI/(count*2)));   IFFT(X,X,r+1);
       dTemp=sqrt(2.0/count);
       d0=(sqrt(1.0/count)-dTemp)*F[0];
       for(i=0;i<count;i++)
       f[i]=d0+X[i].real()*dTemp*2*count;   delete X;
    }
    BOOL WINAPI DIBDct(LPSTR lpDIBBits,LONG lWidth,LONG lHeight)
    {   unsigned char *lpSrc;   long i,j;
       long h=1,w=1;
       int hp=0,wp=0;
       double dTemp;
       long lLineBytes=WIDTHBYTES(lWidth*8);
       while(w*2<=lWidth)
       {
          w*=2;wp++;
       }
       while(h*2<=lHeight)
       {
          h*=2;hp++;
       }
       double *f=new double[w*h];
       double *F=new double[w*h];
       for(i=0;i<h;i++)
       {
          for(j=0;j<w;j++)
          {
     lpSrc=(unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
             f[j+i*w]=*(lpSrc);
          }
       }
       for(i=0;i<h;i++)
       DCT(&f[w*i],&F[w*i],wp);
       for(i=0;i<h;i++)
       {
          for(j=0;j<w;j++)
          f[i+j*h]=F[j+i*w];
       }
       for(j=0;j<w;j++)
       DCT(&f[j*h],&F[j*h],hp);
       for(i=0;i<h;i++)
       {
          for(j=0;j<w;j++)
          {
      dTemp=fabs(F[j*h+i]);
              if(dTemp>255)
              dTemp=255;
              lpSrc=(unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
          *(lpSrc)=(BYTE)(dTemp);
      }
       }
       delete f;
       delete F;
       return TRUE;
    }
    //===============细化========================================
    BOOL WINAPI ThiningDIB(LPSTR lpDIBBits,LONG lWidth,LONG lHeight)
    {   LPSTR lpSrc;
       LPSTR lpDest;
       LPSTR lpNewDIBBits;
       HLOCAL hNewDIBBits;   bool bModified=true;
       long i,j;
       int m,n;
       bool bCondition1,bCondition2,bCondition3,bCondition4;
       unsigned char nCount;
       unsigned char pixel;
       unsigned char neighbour[5][5];
       hNewDIBBits=LocalAlloc(LHND,lWidth*lHeight);
       if(hNewDIBBits==NULL)
       {
       return FALSE;
       }
       lpNewDIBBits=(char*)LocalLock(hNewDIBBits);
       lpDest=(char*)lpNewDIBBits;
       memset(lpDest,(BYTE)255,lWidth*lHeight);    while(bModified)
       {
          bModified=false;
      lpDest=(char*)lpNewDIBBits;
      memset(lpDest,(BYTE)255,lWidth*lHeight);
          
      for(j=2;j<lHeight-2;j++)
          {
              for(i=2;i<lWidth-2;i++)
             {
                bCondition1=false;
                bCondition2=false;
                bCondition3=false;
                bCondition4=false;
                lpSrc=(char*)lpDIBBits+lWidth*j+i;
    lpDest=(char*)lpNewDIBBits+lWidth*j+i;            pixel=(unsigned char)*lpSrc;
                if(pixel!=255&&*lpSrc!=0)
                {
                   return FALSE;
                }
                else if(pixel==255)
                continue;
                for(m=0;m<5;m++)
                {
                  for(n=0;n<5;n++)
                  {                  neighbour[m][n]=(255-(unsigned char)*(lpSrc+((4-m)-2)*lWidth+n-2))/255;
                  }
                }
                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;
                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;           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;           }
               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)
               {
                   *lpDest=(unsigned char)255;
                   bModified=true;
               }
               else *lpDest=(unsigned char)0;
             }
          }
        memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
     
       }
         memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
     
       LocalUnlock(hNewDIBBits);
       LocalFree(hNewDIBBits);
       return TRUE;
    }这是我学图象处理时的代码!
      

  5.   

    怎么叫交接处,是不是一个黑一个白中间加个灰的,灰的就是交接处呀,还是中间不知道有几个点呢?
    如果中间一个点都没有就这样
      pData 指向数据段
     unsigned char *pSor;
     for(i=0;i<lHeight)
        {
         pSor=pData+lWidht*i+91;
         if(i!=lHeight-1)
           {
             if((*(pData+lWidht*(i+1))+91-*pSor)==255))||(*(pData+lWidht*(i+1))+91-*pSor)==-255)));//连着的两行比较一下
           return i;
            }     
        }
      

  6.   

    to: dycdyc123(重出江湖) ,多谢了,我好好研究研究。
    to:   akiy(宏) 交接处就是灰的那一片,具体多灰色区域有多宽是不确定的。