BMP像素获取问题及图像二值化

_葫芦娃 2008-04-29 05:18:40

我的程序中获取了BMP文件像素所在的位置,BYTE * pixel = FindDIBBits(lpDIB); // 得到像素
现在的问题是我如何提取某点的 RGB值了?????

因为我想对BMP图像进行灰度化或者二值化,我计划开以个三位数组来表示处理后的图像位置和像素值。后面还要进行Hough变换。所以要二值化后的BMP图像,因此我计划获取像素后开三位数组。

对于我的问题各位高手能够给个好的建议不?????
请帮忙指导!再好加点程序。

一个初学图像处理的人的困惑!
...全文
520 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
_葫芦娃 2008-05-04
  • 打赏
  • 举报
回复
自己当初只有这么多分,给的"报酬"不多,请见谅.非常感谢大家的支持!
_葫芦娃 2008-05-04
  • 打赏
  • 举报
回复
自己已经解决,谢谢各位了!
_葫芦娃 2008-05-02
  • 打赏
  • 举报
回复
输出还是不对.有那位可以帮帮忙?
嵌云阁主 2008-04-30
  • 打赏
  • 举报
回复
cout < <"R=:" < <(BYTE *)lpPixel < <endl;
=>
cout < <"R=:" < <*(BYTE *)lpPixel < <endl;
knowledge_Is_Life 2008-04-30
  • 打赏
  • 举报
回复
以后需再关注,现在先帮你顶一下
_葫芦娃 2008-04-29
  • 打赏
  • 举报
回复

BYTE * pixel = FindDIBBits(lpDIB); // 得到像素

下面是引用的函数:
BYTE * FindDIBBits(LPBYTE lpbi)//返回DIB图像象素起始位置
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}

我要输出像素值,
for (i = 0; i < height; i ++)
for (j = 0; j < width; j ++)
cout<<"R=:"<<(BYTE *)lpPixel <<endl;
但是输出不对呀?
要怎么处理了,颜色是一个结构体,我要如何引用输出了,请帮忙?
嵌云阁主 2008-04-29
  • 打赏
  • 举报
回复
处理BMP图像要注意每行是以4对齐的,此外有些BMP图像是上下倒置的。
疯魔症 2008-04-29
  • 打赏
  • 举报
回复
图像处理的程序都是千篇一律,顺路我也是初学者
疯魔症 2008-04-29
  • 打赏
  • 举报
回复
我也刚好做到处理24位真彩色了.是这样的24位RGB图像没个像素是3个字节,也就是每一个像素的第一个字节是R,第二个字节是G,第三个字节是B,那么你去的时候你去的时候,先得到像素的指针,(BYTE *)lpPixel就是R了,(BYTE *)lpPixel +1
就是G了,(BYTE *)lpPixel+2就是B了.
_葫芦娃 2008-04-29
  • 打赏
  • 举报
回复
有人可以帮帮不呀?
_葫芦娃 2008-04-29
  • 打赏
  • 举报
回复
// test.cpp :
//C++文件的操作和运算
//请帮忙者自己加个图像!!!!

#include "windows.h"
#include "stdio.h"
#include "iostream"
#include "wtypes.h"

using namespace std;

DECLARE_HANDLE(HDIB);

BOOL LoadBitmapFromFile(LPCTSTR lpFileName,HDIB &hDib); // 打开文件
HGLOBAL CloseBitmapFile(HDIB &hDib); // 关闭文件

BYTE * FindDIBBits(LPBYTE lpbi); // 返回DIB图像象素起始位置
DWORD DIBWidth(LPBYTE lpDIB); // 获取DIB位图的宽度
DWORD DIBHeight(LPBYTE lpDIB); // 获取DIB位图的高度

WORD PaletteSize(LPBYTE lpbi);
WORD DIBNumColors(LPBYTE lpbi);

#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))//判断是否是Win3.0的DIB

//
int main(int argc, CHAR* argv[])
{
HDIB hDib;

BOOL bTrue = LoadBitmapFromFile("C:\\Documents and Settings\\Administrator\\桌面\\新建文件夹\\00.bmp", hDib);

LPBYTE lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDib);

DWORD height = DIBHeight(lpDIB); // 得到图像高度
cout <<"图像高度:"<<height<<endl;

DWORD width = DIBWidth(lpDIB); // 得到图像宽度
cout <<"图像宽度:"<<width<<endl;

// double dwDataSize;

cout<<"输出图像数据的大小:"<</*dwDataSize<<*/endl;

BYTE * pixel = FindDIBBits(lpDIB); // 得到像素


::GlobalUnlock((HGLOBAL) hDib);

if (bTrue)
{
CloseBitmapFile(hDib);
}

// int kk;
// cin>>kk;
return 0;
}

BOOL LoadBitmapFromFile(LPCTSTR lpFileName,HDIB &hDIB)//打开文件指针
{
HANDLE hFile;
BITMAPFILEHEADER bmfHeader;
LPBYTE lpDIB;
DWORD nSize;

hFile = CreateFile(lpFileName,
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL);

if (hFile == INVALID_HANDLE_VALUE)
{ // 文件出错
return FALSE;
}
// 获取DIB(文件)长度(字节)
DWORD dwBitsSize;
dwBitsSize = GetFileSize(hFile, NULL);

cout<<"读取文件的大小:"<<dwBitsSize <<endl;//文件的大小

// 尝试读取DIB文件头
ReadFile(hFile, &bmfHeader, sizeof(bmfHeader), &nSize, NULL);
if (nSize != sizeof(bmfHeader))
{ // 大小不对,返回NULL。
CloseHandle(hFile);
return NULL;
}

// 为DIB分配内存 分配的大小为文件大小
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
// 内存分配失败,返回NULL。
CloseHandle(hFile);
return NULL;
}

// 锁定
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

// 读象素
ReadFile(hFile, lpDIB, dwBitsSize - sizeof(BITMAPFILEHEADER), &nSize, NULL);

// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);

CloseHandle(hFile);

if (nSize != dwBitsSize - sizeof(BITMAPFILEHEADER) )
{
// 大小不对, 释放内存
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
else
{
return TRUE;
}
}

HGLOBAL CloseBitmapFile(HDIB &hDib)
{
return ::GlobalFree((HGLOBAL) hDib);
}

BYTE * FindDIBBits(LPBYTE lpbi)//返回DIB图像象素起始位置
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}

DWORD DIBWidth(LPBYTE lpDIB)//获取DIB位图的宽度
{
// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFOHEADER lpbmi;

// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREHEADER lpbmc;

// 获取指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;

// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
// 对于Windows 3.0 DIB,返回lpbmi->biWidth
return lpbmi->biWidth;
}
else
{
// 对于其它格式的DIB,返回lpbmc->bcWidth
return (DWORD)lpbmc->bcWidth;
}
}

DWORD DIBHeight(LPBYTE lpDIB)//获取DIB位图高度
{
// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFOHEADER lpbmi;

// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREHEADER lpbmc;

// 获取指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;

// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
// 对于Windows 3.0 DIB,返回lpbmi->biHeight
return lpbmi->biHeight;
}
else
{
// 对于其它格式的DIB,返回lpbmc->bcHeight
return (DWORD)lpbmc->bcHeight;
}
}

WORD PaletteSize(LPBYTE lpbi) //返回DIB调色板大小
{
// 计算DIB中调色板的大小
if (IS_WIN30_DIB (lpbi))
{
//返回颜色数目×RGBQUAD的大小
return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));
}
else
{
//返回颜色数目×RGBTRIPLE的大小
return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
}
}

WORD DIBNumColors(LPBYTE lpbi)//计算DIB调色板颜色数目,返回调色板中颜色的种数
{
int nBitCount;
// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。
// 对于这种情况,则返回一个近似的数值。

if (IS_WIN30_DIB(lpbi)) // 判断是否是WIN3.0 DIB
{
// 读取dwClrUsed值
DWORD dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;

if (dwClrUsed != 0)
{
// 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值
return (WORD)dwClrUsed;
}
}

// 读取象素的位数
if (IS_WIN30_DIB(lpbi))
{
// 读取biBitCount值
nBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
}
else
{
// 读取biBitCount值
nBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
}

// 按照象素的位数计算颜色数目
switch (nBitCount)
{
case 1:
return 2;

case 4:
return 16;

case 8:
return 256;
default:
return 0;
}
}

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧