标题:关于灰度直方图的问题
只看楼主
yuxudaoren
Rank: 1
等 级:新手上路
帖 子:63
专家分:0
注 册:2006-3-24
 问题点数:0 回复次数:8 
关于灰度直方图的问题

将8位bmp位图的灰度直方图代码改为24位的之后出现异常错误,检查之后没有发现溢出越界之类的错误,请大家帮忙看看,这是部分代码:
#include "stdafx.h"
#include "sw.h"
#include "dlgIntensity.h"
#include "DIBAPI.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CdlgIntensity dialog


CdlgIntensity::CdlgIntensity(CWnd* pParent /*=NULL*/)
: CDialog(CdlgIntensity::IDD, pParent)
{
//{{AFX_DATA_INIT(CdlgIntensity)
m_iLowGray = 0;
m_iUpGray = 0;
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}


void CdlgIntensity::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CdlgIntensity)
DDX_Text(pDX, IDC_EDIT_LowGray, m_iLowGray);
DDV_MinMaxInt(pDX, m_iLowGray, 0, 16777216);
DDX_Text(pDX, IDC_EDIT_UpGray, m_iUpGray);
DDV_MinMaxInt(pDX, m_iUpGray, 0, 16777216);
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CdlgIntensity, CDialog)
//{{AFX_MSG_MAP(CdlgIntensity)
ON_WM_PAINT()
ON_EN_KILLFOCUS(IDC_EDIT_LowGray, OnKillfocusEDITLowGray)
ON_EN_KILLFOCUS(IDC_EDIT_UpGray, OnKillfocusEDITUpGray)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CdlgIntensity message handlers
BOOL CdlgIntensity::OnInitDialog()
{
// 指向源图像象素的指针
unsigned char * lpSrc;

// 循环变量
LONG i;
LONG j;

// 调用默认OnInitDialog函数
CDialog::OnInitDialog();

// 获取绘制直方图的标签
CWnd* pWnd = GetDlgItem(IDC_COORD);

// 计算接受鼠标事件的有效区域
pWnd->GetClientRect(m_MouseRect);
pWnd->ClientToScreen(&m_MouseRect);

CRect rect;
GetClientRect(rect);
ClientToScreen(&rect);

m_MouseRect.top -= rect.top;
m_MouseRect.left -= rect.left;

// 设置接受鼠标事件的有效区域
m_MouseRect.top += 25;
m_MouseRect.left += 10;
m_MouseRect.bottom = m_MouseRect.top + 16777215;
m_MouseRect.right = m_MouseRect.left + 16777216;

// 重置计数为0
for (i = 0; i < 16777216; i ++)
{
// 清零
m_lCount[i] = 0;
}

// 图像每行的字节数
LONG lLineBytes;

// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(m_lWidth * 8);

// 计算各个灰度值的计数
for (i = 0; i < m_lHeight; i ++)
{
for (j = 0; j < m_lWidth; j ++)
{
lpSrc = (unsigned char *)m_lpDIBBits + lLineBytes * i + j;

// 计数加1
m_lCount[*(lpSrc)]++;
}
}

// 初始化拖动状态
m_iIsDraging = 0;

// 返回TRUE
return TRUE;

}
void CdlgIntensity::OnKillfocusEDITLowGray()
{
// 保存变动(控件中数值保存到成员变量中)
UpdateData(TRUE);

// 判断是否下限超过上限
if (m_iLowGray > m_iUpGray)
{
// 互换
int iTemp = m_iLowGray;
m_iLowGray = m_iUpGray;
m_iUpGray = iTemp;

// 更新(成员变量中数值保存到控件中)
UpdateData(FALSE);
}

// 重绘直方图
InvalidateRect(m_MouseRect, TRUE);
}

void CdlgIntensity::OnKillfocusEDITUpGray()
{
// 保存变动
UpdateData(TRUE);

// 判断是否下限超过上限
if (m_iLowGray > m_iUpGray)
{
// 互换
int iTemp = m_iLowGray;
m_iLowGray = m_iUpGray;
m_iUpGray = iTemp;

// 更新
UpdateData(FALSE);
}

// 重绘直方图
InvalidateRect(m_MouseRect, TRUE);

}

void CdlgIntensity::OnLButtonDown(UINT nFlags, CPoint point)
{
// 当用户单击鼠标左键开始拖动

// 判断是否在接受鼠标事件的有效区域中
if(m_MouseRect.PtInRect(point))
{
if (point.x == (m_MouseRect.left + m_iLowGray))
{

// 设置拖动状态1,拖动下限
m_iIsDraging = 1;

// 更改光标
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
}
else if (point.x == (m_MouseRect.left + m_iUpGray))
{

// 设置拖动状态为2,拖动上限
m_iIsDraging = 2;

// 更改光标
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
}
}

// 默认单击鼠标左键处理事件
CDialog::OnLButtonDown(nFlags, point);
}

void CdlgIntensity::OnMouseMove(UINT nFlags, CPoint point)
{

// 判断是否在接受鼠标事件的有效区域中
if(m_MouseRect.PtInRect(point))
{
// 判断是否正在拖动
if (m_iIsDraging != 0)
{
// 判断正在拖动上限还是下限
if (m_iIsDraging == 1)
{
// 判断是否下限<上限
if (point.x - m_MouseRect.left < m_iUpGray)
{
// 更改下限
m_iLowGray = point.x - m_MouseRect.left;
}
else
{
// 下限拖过上限,设置为上限-1
m_iLowGray = m_iUpGray - 1;

// 重设鼠标位置
point.x = m_MouseRect.left + m_iUpGray - 1;
}
}
else
{
// 正在拖动上限

// 判断是否上限>下限
if (point.x - m_MouseRect.left > m_iLowGray)
{
// 更改下限
m_iUpGray = point.x - m_MouseRect.left;
}
else
{
// 下限拖过上限,设置为下限+1
m_iUpGray = m_iLowGray + 1;

// 重设鼠标位置
point.x = m_MouseRect.left + m_iLowGray + 1;
}
}

// 更改光标
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));

// 更新
UpdateData(FALSE);

// 重绘直方图
InvalidateRect(m_MouseRect, TRUE);
}
else if (point.x == (m_MouseRect.left + m_iLowGray) || point.x == (m_MouseRect.left + m_iUpGray))
{
// 更改光标
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
}
}

// 默认鼠标移动处理事件
CDialog::OnMouseMove(nFlags, point);
}

void CdlgIntensity::OnLButtonUp(UINT nFlags, CPoint point)
{
// 当用户释放鼠标左键停止拖动
if (m_iIsDraging != 0)
{
// 重置拖动状态
m_iIsDraging = 0;
}

// 默认释放鼠标左键处理事件
CDialog::OnLButtonUp(nFlags, point);
}

void CdlgIntensity::OnPaint()
{
// 字符串
CString str;

// 循环变量
LONG i;

// 最大计数
LONG lMaxCount = 0;

// 设备上下文
CPaintDC dc(this);

// 获取绘制坐标的文本框
CWnd* pWnd = GetDlgItem(IDC_COORD);

// 指针
CDC* pDC = pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();

pDC->Rectangle(0,0,330,300);

// 创建画笔对象
CPen* pPenRed = new CPen;

// 红色画笔
pPenRed->CreatePen(PS_SOLID,1,RGB(16777215,0,0));

// 创建画笔对象
CPen* pPenBlue = new CPen;

// 蓝色画笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 16777215));

// 创建画笔对象
CPen* pPenGreen = new CPen;

// 绿色画笔
pPenGreen->CreatePen(PS_DOT,1,RGB(0,16777215,0));

// 选中当前红色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);

// 绘制坐标轴
pDC->MoveTo(10,10);

// 垂直轴
pDC->LineTo(10,280);

// 水平轴
pDC->LineTo(320,280);

// 写X轴刻度值
str.Format("0");
pDC->TextOut(10, 283, str);
str.Format("50");
pDC->TextOut(60, 283, str);
str.Format("100");
pDC->TextOut(110, 283, str);
str.Format("150");
pDC->TextOut(160, 283, str);
str.Format("200");
pDC->TextOut(210, 283, str);
str.Format("255");
pDC->TextOut(265, 283, str);

// 绘制X轴刻度
for (i = 0; i < 16777216; i += 5)
{
if ((i & 1) == 0)
{
// 10的倍数
pDC->MoveTo(i + 10, 280);
pDC->LineTo(i + 10, 284);
}
else
{
// 10的倍数
pDC->MoveTo(i + 10, 280);
pDC->LineTo(i + 10, 282);
}
}

// 绘制X轴箭头
pDC->MoveTo(315,275);
pDC->LineTo(320,280);
pDC->LineTo(315,285);

// 绘制X轴箭头
pDC->MoveTo(10,10);
pDC->LineTo(5,15);
pDC->MoveTo(10,10);
pDC->LineTo(15,15);

// 计算最大计数值
for (i = m_iLowGray; i <= m_iUpGray; i ++)
{
// 判断是否大于当前最大值
if (m_lCount[i] > lMaxCount)
{
// 更新最大值
lMaxCount = m_lCount[i];
}
}

// 输出最大计数值
pDC->MoveTo(10, 25);
pDC->LineTo(14, 25);
str.Format("%d", lMaxCount);
pDC->TextOut(11, 26, str);

// 更改成绿色画笔
pDC->SelectObject(pPenGreen);

// 绘制窗口上下限
pDC->MoveTo(m_iLowGray + 10, 25);
pDC->LineTo(m_iLowGray + 10, 280);

pDC->MoveTo(m_iUpGray + 10, 25);
pDC->LineTo(m_iUpGray + 10, 280);

// 更改成蓝色画笔
pDC->SelectObject(pPenBlue);

// 判断是否有计数
if (lMaxCount > 0)
{
// 绘制直方图
for (i = m_iLowGray; i <= m_iUpGray; i ++)
{
pDC->MoveTo(i + 10, 280);
pDC->LineTo(i + 10, 281 - (int) (m_lCount[i] * 16777216 / lMaxCount));
}
}

// 恢复以前的画笔
pDC->SelectObject(pOldPen);

// 删除新的画笔
delete pPenRed;
delete pPenBlue;
delete pPenGreen;

}

void CdlgIntensity::OnOK()
{

// 判断是否下限超过上限
if (m_iLowGray > m_iUpGray)
{
// 互换
int iTemp = m_iLowGray;
m_iLowGray = m_iUpGray;
m_iUpGray = iTemp;
}

// 返回
CDialog::OnOK();
}

搜索更多相关主题的帖子: 灰度 quot include FILE DEBUG 
2006-08-06 08:59
chenzd
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-7-12
得分:0 
我想问一下,你这里RGB为什么范围这么大,不是0到255吗,RGB(16777215,0,0)

2006-08-06 10:01
yuxudaoren
Rank: 1
等 级:新手上路
帖 子:63
专家分:0
注 册:2006-3-24
得分:0 
回复:(chenzd)我想问一下,你这里RGB为什么范围这么...
   处理24位色的话不应该是16777215么?
2006-08-06 10:12
chenzd
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-7-12
得分:0 
256*256*256=16777216

2006-08-06 10:18
yuxudaoren
Rank: 1
等 级:新手上路
帖 子:63
专家分:0
注 册:2006-3-24
得分:0 
回复:(chenzd)256*256*256=16777216

从0开始不就是 16777215么 颜色范围应该是(0,16777215)不对么?
2006-08-06 10:21
chenzd
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-7-12
得分:0 

RGB()用8位三原色来表示颜色,每种颜色256个灰度级,所以一共24位
如果是RGB(16777215,0,0),那么是24+24+24位了

[此贴子已经被作者于2006-8-6 14:38:39编辑过]


2006-08-06 10:29
yuxudaoren
Rank: 1
等 级:新手上路
帖 子:63
专家分:0
注 册:2006-3-24
得分:0 
回复:(chenzd)RGB()用8位三原色来表示颜色,每种颜...

那就是说还用(255,0,0)这种来处理24位bmp图么
还请帮忙看一下如何修改为处理24位图的灰度直方图

2006-08-06 10:34
yuxudaoren
Rank: 1
等 级:新手上路
帖 子:63
专家分:0
注 册:2006-3-24
得分:0 
      大家帮帮忙  看看问题在哪里 谢谢
2006-08-06 14:06
chenzd
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-7-12
得分:0 

最近我也在弄灰度图的问题,但用RGB(x,x,x),x=[0,255],只能处理8位灰度图象,我用SetPixel(x,y,RGB(,,)),将图像卡上采来的一帧8位灰度图逐像素画出来,效果相当差,看上去好像只有4个灰度级,而不是256个,希望知情者点拨一下


2006-08-06 14:38



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-82358-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.499176 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved