请文各位高手,如何在vc++创建直方图,并且如何操作,给出相应代码?

解决方案 »

  1.   

    找本数字图象处理的书看看.邮电出版社的<VC++数字图像处理>不错,也有实例.
      

  2.   

    呵呵,不知道直接拿出东东到底是应该还是不应该。不过想到当初某人捣弄这些时候的景况,还是直接带入代码了罢。直接copy下边的代码,可以得到灰度直方图(但愿没有落下什么大的地方)。
    bmp图象格式、调色板、rgb什么的,默认为熟悉。*_*
    还有,至于怎么gui显示出来,呵呵,俺就不管啦。自定义的图象类中的得到直方图函数,参数iClrChannel为rgb分量之一,piGrays为该分量的256灰度级。
    void CImage::GetHistogram(int *piGrays, int iClrChannel)
    {
    if(m_hBmp == NULL) return;
    for(int i = 0; i < 256; i++)
    {
    piGrays[i] = 0;
    }
    ASSERT(iClrChannel >= 0 && iClrChannel <= 3);
    LPSTR lpBmp = (LPSTR)GlobalLock(m_hBmp);
    BYTE* lpBmpBits = (BYTE*)GetBmpBits(lpBmp); CRect rcData = GetDataRect();
    int row, col;
    int iPixel=0;
    BYTE r, g, b;
    r = g = b = 0; switch(m_nBitCount)
    {
    case 24:
    {
    if(iClrChannel == 3/*luminary*/)
    {
    BYTE* pData = NULL;
    for(row=rcData.top; row<rcData.bottom; row++)
    {
    for(col=rcData.left;col<rcData.right;col++)
    {
    pData = (BYTE*)lpBmpBits 
    + row * m_nScanWidth + 3*col;
    piGrays[(pData[0]+pData[1]+pData[2])/3]++;
    }
    }
    }
    else
    {
      for(row = rcData.top; row < rcData.bottom; row++)
      {
    iPixel =  iClrChannel + row * m_nScanWidth 
    + rcData.left*3;//origin pix of the row
    for(col = rcData.left; col < rcData.right; col++)
    {
    piGrays[lpBmpBits[iPixel]]++;
    iPixel += 3;
    }
      }
    }
    break;
    }
    case 8:
    {
    PALETTEENTRY PaletteColors[256];
    if(m_pPalBmp->GetPaletteEntries(0, 256, PaletteColors)
    != 256 ) break;
    for(row = rcData.top; row < rcData.bottom; row++)
    {
    iPixel = row * m_nScanWidth + rcData.left;
    for(col = rcData.left; col < rcData.right; col++)
    {
    r = PaletteColors[lpBmpBits[iPixel]].peRed;
    g = PaletteColors[lpBmpBits[iPixel]].peGreen;
    b = PaletteColors[lpBmpBits[iPixel]].peBlue;
    iPixel++;
    switch(iClrChannel)
    {
    case 3:/*lum*/ piGrays[(r+g+b)/3]++;break;
    case 2:/*red*/ piGrays[r]++;break;
    case 1:/*green*/
    piGrays[g]++;break;
    case 0:/*blue*/ piGrays[b]++;break;
    }
    }
    }
    break;
    }
    }
    GlobalUnlock(m_hBmp);
    }m_hBmp为bmp图象中除去bmpfileheader后的数据,也就是PBMPINFOHEADER这个指针。用的HANDLE,所以需要先“GlobalLock”。
    用这个函数得到:HANDLE WINAPI ReadBmpFile(CFile& file)
    {
    BITMAPFILEHEADER bmfHeader;
    DWORD dwBitsSize;
    HANDLE hBMP;
    LPSTR pBMP; //get length of Bmp in bytes for use when reading
    dwBitsSize = file.GetLength(); //Go read the Bmp file header and check if it's valid.
    file.SeekToBegin();
    if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
    {
    file.Close();
    return NULL;
    } if (bmfHeader.bfType != BMP_FILE_TYPE)
    {
    CString str1, str2;
    str1.Format("此程序只能处理 BMP 图片!");
    str2.Format("文件格式错误");
    ::MessageBox(NULL,str1,str2,MB_ICONERROR|MB_OK); file.Close();
    return NULL;
    }
    //Allocate memory for Bmp
    hBMP = (HANDLE) ::GlobalAlloc(GHND, dwBitsSize);
    if (hBMP == 0)
    {
    file.Close();
    return NULL;
    }
    pBMP = (LPSTR) ::GlobalLock((HGLOBAL) hBMP); // read the bits.
     
    if (file.ReadHuge(pBMP, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
    dwBitsSize - sizeof(BITMAPFILEHEADER) )
    {
    ::GlobalUnlock((HGLOBAL) hBMP);
    ::GlobalFree((HGLOBAL) hBMP);
    file.Close();
    return NULL;
    }

    file.Close();
    ::GlobalUnlock((HGLOBAL) hBMP);
    return hBMP;
    }GetBmpBits函数用来得到图象数据。
    LPSTR WINAPI GetBmpBits(LPSTR lpBmp)
    {
    return (lpBmp + *(LPDWORD)lpBmp + PaletteSize(lpBmp));
    }对24位色图象来说,用上边的东东就可以得到灰度直方图。对8位(256)色图象来说,需要调色板的介入。
    WORD WINAPI PaletteSize(LPSTR lpBmp)
    {
       // calculate the size required by the palette
       if (IS_WIN30_BMP (lpBmp))
      return (WORD)(::BmpNumColors(lpBmp) * sizeof(RGBQUAD));
       else
      return (WORD)(::BmpNumColors(lpBmp) * sizeof(RGBTRIPLE));
    }WORD WINAPI BmpNumColors(LPSTR lpBmp)
    {
    WORD wBitCount;  // Bmp bit count /*  Calculate the number of colors in the color table based on
     *  the number of bits per pixel for the Bmp.
     */
    if (IS_WIN30_BMP(lpBmp))
    wBitCount = ((LPBITMAPINFOHEADER)lpBmp)->biBitCount;
    else
    wBitCount = ((LPBITMAPCOREHEADER)lpBmp)->bcBitCount; /* return number of colors based on bits per pixel */
    switch (wBitCount)
    {
    case 1:
    return 2; case 4:
    return 16; case 8:
    return 256; default:
    return 0;
    }
    }得到调色板:
    BOOL WINAPI CreateBmpPalette(HANDLE hBmp, CPalette* pPal)
    {
    LPLOGPALETTE lpPal;     // pointer to a logical palette
    HANDLE hLogPal;         // handle to a logical palette
    WORD wNumColors;        // number of colors in color table
    LPSTR lpBmp;            // pointer to packed-Bmp
    LPBITMAPINFO lpbmi;     // pointer to BITMAPINFO structure (Win3.0)
    LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
    BOOL bResult=FALSE; // return value //if handle to Bmp is invalid, return FALSE
    if (hBmp == NULL)
      return FALSE;   lpBmp = (LPSTR) ::GlobalLock((HGLOBAL) hBmp);   // get pointer to BITMAPINFO (Win 3.0)
       lpbmi = (LPBITMAPINFO)lpBmp;   // get pointer to BITMAPCOREINFO (OS/2)
       lpbmc = (LPBITMAPCOREINFO)lpBmp;   // get the number of colors in the Bmp
       wNumColors = BmpNumColors(lpBmp);   if(wNumColors ==0 ) //there is no palette in the bmp
       return FALSE; // allocate memory block for logical palette 
    hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
    + sizeof(PALETTEENTRY)
    * wNumColors); // if three is not enough memory, clean up and return NULL 
    if (hLogPal == 0)
    {
    ::GlobalUnlock((HGLOBAL) hBmp);
    return FALSE;
    } lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); //set version and number of palette entries 
    lpPal->palVersion = PALVERSION;
    lpPal->palNumEntries = (WORD)wNumColors; if (IS_WIN30_BMP(lpBmp)) // is this a Win 3.0 Bmp? 
    for (int i = 0; i < (int)wNumColors; i++)
    {
    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
    for (int i = 0; i < (int)wNumColors; i++)
    {
    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;
    } //create the palette and get handle to it
    bResult = pPal->CreatePalette(lpPal);
    ::GlobalUnlock((HGLOBAL) hLogPal);
    ::GlobalFree((HGLOBAL) hLogPal); ::GlobalUnlock((HGLOBAL) hBmp); return bResult;
    }
      

  3.   

    纠结,这么长..http://book.csdn.net/bookfiles/974/10097430288.shtml