高手来看看,这个二值化的处理问题处在哪里

henrythoreau 2009-03-27 04:46:28
不论设置阈值为多少,处理结果是图像变成纯白(就是图像没有了)
void CXXXView::OnBinary()
{
CBinaryDlg binaryDlg;
if(binaryDlg.DoModal() == IDOK)
{
CShuFaDoc* pDoc = GetDocument();
pDoc->m_pDib->Binary(binaryDlg.m_nThre);
pDoc->SetModifiedFlag(TRUE);
OnRealizePal((WPARAM)m_hWnd,0); // realize the new palette
pDoc->UpdateAllViews(NULL);
}
}

BOOL CDib::Binary(BYTE bThre)
{
HDIB hNewDib = ThresholdDIB(m_hDib, bThre);
if(! hNewDib)
return FALSE;
// set to m_hDib
Destroy();
m_hDib = hNewDib;
// return
return UpdateInternal();
}

HDIB ThresholdDIB(HDIB hDIB, BYTE bThre)
{
WaitCursorBegin();

// Get source bitmap info
LPBITMAPINFO lpBmInfo = (LPBITMAPINFO)GlobalLock(hDIB);

int bpp = lpBmInfo->bmiHeader.biBitCount; // Bits per pixel
int nWidth = lpBmInfo->bmiHeader.biWidth;
int nHeight = lpBmInfo->bmiHeader.biHeight;
int nRowBytes = ((((nWidth * bpp) + 31) & ~31) / 8);

// Make sure height is positive and biCompression is BI_RGB or BI_BITFIELDS
DWORD compression = lpBmInfo->bmiHeader.biCompression;

if(nHeight < 0 || (compression != BI_RGB))
{
GlobalUnlock(hDIB);
WaitCursorEnd();

return NULL;
}

LPBYTE lpDIBBits = FindDIBBits((LPBYTE)lpBmInfo);

unsigned char *lpSrc;

for(int i = 0; i < nHeight; i++)
{
for(int j = 0; j < nWidth; j++)
lpSrc = lpDIBBits + nRowBytes * (nHeight - 1 - i) + j;

if((*lpSrc) < bThre)
{
*lpSrc = 0;
}
else
{
*lpSrc = 255;
}
}

GlobalUnlock(hDIB);

WaitCursorEnd();

return hDIB;
}
...全文
165 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
cnzdgs 2009-03-29
  • 打赏
  • 举报
回复
是256色图象?
henrythoreau 2009-03-29
  • 打赏
  • 举报
回复
我处理的是灰度图像
7楼的法子不行,结果还是那样
不过还是谢谢你了
zkhraul 2009-03-29
  • 打赏
  • 举报
回复
你是处理8位图吧,lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j*3;
henrythoreau 2009-03-28
  • 打赏
  • 举报
回复
应该是这个表达式出了问题。
lpSrc = lpDIBBits + nRowBytes * (nHeight - 1 - i) + j;
断点调试了一下,是个很大的负数
这样无论设什么阈值,都是执行 ×lpSrc = 0;

谁能告诉我这句该怎么该?
cnzdgs 2009-03-28
  • 打赏
  • 举报
回复
你要处理的图是多少位色的?例如24位色,每个像素3字节,横坐标需要乘以3,然后要分别取R、G、B的值,判断后统一填255或0。
henrythoreau 2009-03-28
  • 打赏
  • 举报
回复
我检查发现第二个For循环体忘了加{},但是加上后结果还是一样的
急呀,怎么没人回呢
moreslow 2009-03-27
  • 打赏
  • 举报
回复
在这里设个断点单步执行看看咯
if((*lpSrc) < bThre)
{
*lpSrc = 0;
}
else
{
*lpSrc = 255;
}
cnzdgs 2009-03-27
  • 打赏
  • 举报
回复
可以先把所有像素的颜色都加在一起,再除以像素数量求得平均者作为阈值。
henrythoreau 2009-03-27
  • 打赏
  • 举报
回复
以下是资料上的源码,为了融进现有的平台,改造为上述形式。
高手帮忙看看,问题在哪?编译和运行都没有问题,就是处理结果不对。

//参数说明:
//LPSTR lpDIBBits:指向源DIB图像指针
//LONG lWidth:源图像宽度(象素数)
//LONG lHeight:源图像高度(象素数)
//BYTE bThre:阈值
//程序说明:
//该函数用来对图像进行阈值变换。对于灰度值小于阈值的象素直接设置
灰度值为0;灰度值大于阈值的象素直接设置为255。
BOOL WINAPI ThresholdTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre)
{
// 指向源图像的指针
unsigned char* lpSrc;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;

// 判断是否小于阈值
if ((*lpSrc) < bThre)
{
// 直接赋值为0
*lpSrc = 0;
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
// 返回
return TRUE;
}

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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