彩色图像转为灰度图,求助

xio_xia 2015-11-07 12:06:43
源代码为:
前面已经获得了图像的像素
LRESULT CJVSDKDEMODlg::OnSDKNotify(WPARAM wParam, LPARAM lParam)
{
if (lParam == JVS_WM_COPYRIGHT)
{
//
}
else if (lParam == JVS_WM_BITMAP_OK)
{
int nChannel = wParam;
if (nChannel<0 || nChannel > JDVR_MAX_CHANNEL)
{
return FALSE;
}
if (g_config.Channel[nChannel].Bitmap.pRGB == NULL)
{
return FALSE;
}
int nWidth = g_config.Channel[0].Bitmap.dwWidth;
int nHeight = g_config.Channel[0].Bitmap.dwHeight;
int nBits = 4;
ULONG ulSize = nWidth * nHeight * nBits;
FILE * fout = fopen("bitmap.bmp", "wb");
if (fout)
{
BITMAPFILEHEADER bmHeader;
memset(&bmHeader, 0, sizeof(bmHeader));
bmHeader.bfType = 0x4D42;
bmHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nWidth * nHeight * nBits;
bmHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

BITMAPINFOHEADER bmInfo;
memset(&bmInfo, 0, sizeof(bmInfo));
bmInfo.biSize = sizeof(bmInfo);
bmInfo.biWidth = nWidth;
bmInfo.biHeight = nHeight;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = nBits * 8; // 32bit // 这句不明白,求解释哦
// 我的理解是彩色图(如bmp)每个 像素大小为四个字节,为何此处定义为4个字节)
bmInfo.biCompression = 0;
bmInfo.biSizeImage = nWidth * nHeight * nBits; // 实际图像占用的字节数
bmInfo.biXPelsPerMeter = 300;
bmInfo.biYPelsPerMeter = 300;

fwrite(&bmHeader, sizeof(bmHeader), 1, fout);
fwrite(&bmInfo, sizeof(bmInfo), 1, fout);
fwrite(g_config.Channel[nChannel].Bitmap.pRGB, nWidth * nHeight * nBits, 1, fout);

fclose(fout);
m_lstInfo.SetCurSel(m_lstInfo.AddString("Capture to \"bitmap.bmp\""));

// ********************************** 绘制位图***********************
DWORD count = nWidth * nHeight * nBits;
unsigned char* buff = new unsigned char[count];
unsigned char* buff_out = new unsigned char[count];
//int* buff_out = new int[count];
unsigned char ImgMax = 0;
unsigned char ImgMin = 0;
//ImgMax = ceil(0.9*255) - 20;
//ImgMin = ceil(0.1*100) + 100;
ImgMax = 255;
ImgMin = 100;
//输入图像每像素字节数,彩色图像为4字节/像素
int pixelByteIn=4;
//输入图像每行像素所占字节数,必须是4的倍数
int lineByteIn=(nWidth*pixelByteIn+ 3)/4*4; // + 3
//灰值化后,每像素位数为8比特
int m_nBitCountOut=8;
//输出图像每行像素所占字节数,必须是4的倍数
int lineByteOut=(nWidth*m_nBitCountOut/8+ 3)/4*4; // +3
int i = 0,j = 0;
for(i = 0; i < nHeight; ++i)
{
memcpy(&buff[i*nWidth*nBits],&(g_config.Channel[nChannel].Bitmap.pRGB[(nHeight - i) * nWidth * nBits]),nWidth * nBits);
}

for(i = 0; i < nHeight; ++i)
{
for(j = 0; j < nWidth; ++j)
{
//根据灰值化公式为输出图像赋值
*(buff_out+i*nWidth*nBits+j)=(0.30**(buff+i*nWidth*nBits+j*pixelByteIn+1) //*lineByteOut
+0.59**(buff+i*nWidth*nBits+j*pixelByteIn+2)
+0.11**(buff+i*nWidth*nBits+j*pixelByteIn+3)+0.5); // 转换为灰度图的像素数据 有点问题?求解
ImgTemp = int(*(buff_out+i*nWidth*nBits+j) - ImgMin);
// 这下面为通过线性拉伸,增强图像的对比度,下面的操作出错了,在MATLAB中仿真是正确的,在这就出错了,估计是数据大小这一块没明白,求解释。
if (ImgTemp < 0)
{
*(buff_out+i*nWidth*nBits+j) = 0;
}
else
{
ImgTemp = int((abs(*(buff_out+i*nWidth*nBits+j) - ImgMin))/(ImgMax - ImgMin)*255);
if (ImgTemp > 255)
{
*(buff_out+i*nWidth*nBits+j) = 255;
}
else
{
*(buff_out+i*nWidth*nBits+j) = (abs(*(buff_out+i*nWidth*nBits+j) - ImgMin))/(ImgMax - ImgMin)*255;
}
}

}
}

CBitmap bitmap;
bitmap.CreateBitmap(nWidth ,nHeight ,1,(nBits) * 8,buff_out);

CWnd* pWnd = GetDlgItem(IDC_SHOW_IMAGE);
CDC* dc = pWnd->GetDC();
CDC MemDC;
MemDC.CreateCompatibleDC(dc);
MemDC.SelectObject(&bitmap);
CRect rect;
pWnd->GetClientRect(&rect);
dc->SetStretchBltMode(HALFTONE);
int bmpPro = 1;
dc->StretchBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,bmpPro*rect.Width(),bmpPro*rect.Height(),SRCCOPY);
//dc->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);//显示位图
//释放RGB缓冲
delete[] g_config.Channel[nChannel].Bitmap.pRGB;
g_config.Channel[nChannel].Bitmap.pRGB = NULL;
}
}
return TRUE;
}

求指导,刚开始接触图像方面。
...全文
213 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
xio_xia 2015-11-11
  • 打赏
  • 举报
回复
引用 8 楼 shao99 的回复:
里面有demo,可以看看,用起来很简单的
谢谢哈,看到了,学习一下,之前在哪看过另一段代码,挺好得
shao99 2015-11-10
  • 打赏
  • 举报
回复
里面有demo,可以看看,用起来很简单的
shao99 2015-11-10
  • 打赏
  • 举报
回复
引用 5 楼 u013285144 的回复:
@shao99 CxImage类库 如何使用,希望给个链接,之前没有接触过这方面的,刚开始,谢谢哈 还有,这个苦衷是否有将图像转为灰度图的函数或方法;是否有增强灰度图对比度的方法,再次感谢
这些功能都有。 http://www.codeproject.com/Articles/1300/CxImage
shao99 2015-11-09
  • 打赏
  • 举报
回复
我是用CxImage类库,直接有灰度化转换函数的。
xio_xia 2015-11-09
  • 打赏
  • 举报
回复
[quote=引用 3 楼 worldy 的回复:] 参考一下我改动过的注释, 谢谢哈,这个代码我看懂了 不过就是 还有一步转化为灰度图进行线性拉伸,结果不对,麻烦看一下,这是代码: //根据灰值化公式为输出图像赋值 *(buff_out+i*lineByteOut+j)=(0.30**(buff+i*lineByteIn+j*pixelByteIn+1) //*lineByteOut +0.59**(buff+i*lineByteIn+j*pixelByteIn+2) +0.11**(buff+i*lineByteIn+j*pixelByteIn+3)+0.5); ImgTemp = int(*(buff_out+i*lineByteOut+j) - ImgMin); if (ImgTemp < 0) { *(buff_out+i*lineByteOut+j) = 0; } else { ImgTemp = int((abs(*(buff_out+i*lineByteOut+j) - ImgMin))/(ImgMax - ImgMin)); if (ImgTemp > 255) { *(buff_out+i*lineByteOut+j) = 255; } else { *(buff_out+i*lineByteOut+j) = unsigned char (ImgTemp); // unsigned char } }
xio_xia 2015-11-09
  • 打赏
  • 举报
回复
@shao99 CxImage类库 如何使用,希望给个链接,之前没有接触过这方面的,刚开始,谢谢哈

还有,这个苦衷是否有将图像转为灰度图的函数或方法;是否有增强灰度图对比度的方法,再次感谢
worldy 2015-11-07
  • 打赏
  • 举报
回复
参考一下我改动过的注释,
LRESULT CJVSDKDEMODlg::OnSDKNotify(WPARAM wParam, LPARAM lParam)
{
	if (lParam == JVS_WM_COPYRIGHT)
	{
		//
	}
	else if (lParam == JVS_WM_BITMAP_OK)	
	{
		int nChannel = wParam;
		if (nChannel<0 || nChannel > JDVR_MAX_CHANNEL)
		{
			return FALSE;
		}
		if (g_config.Channel[nChannel].Bitmap.pRGB == NULL)
		{
			return FALSE;
		}
		int nWidth = g_config.Channel[0].Bitmap.dwWidth;
		int nHeight = g_config.Channel[0].Bitmap.dwHeight;
		int nBits = 4;
		ULONG ulSize = nWidth * nHeight * nBits;
		FILE * fout = fopen("bitmap.bmp", "wb");
		if (fout)
		{
			BITMAPFILEHEADER bmHeader;
			memset(&bmHeader, 0, sizeof(bmHeader));
			bmHeader.bfType = 0x4D42;
			bmHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nWidth * nHeight * nBits;
			bmHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

			BITMAPINFOHEADER bmInfo;
			memset(&bmInfo, 0, sizeof(bmInfo));
			bmInfo.biSize = sizeof(bmInfo);
			bmInfo.biWidth	=	nWidth;
			bmInfo.biHeight	=	nHeight;
			bmInfo.biPlanes	=	1;
			bmInfo.biBitCount	=	nBits * 8;   //每个像素位数32位,虽然这个符号nBits有点蛋疼,但是前面已经定义是4了,应该nBytes更合理些


			bmInfo.biCompression	=	0;
			bmInfo.biSizeImage	=	nWidth * nHeight * nBits;           // 实际图像占用的字节数
			bmInfo.biXPelsPerMeter	=	300;
			bmInfo.biYPelsPerMeter	=	300;

			fwrite(&bmHeader, sizeof(bmHeader), 1, fout);
			fwrite(&bmInfo, sizeof(bmInfo), 1, fout);
			fwrite(g_config.Channel[nChannel].Bitmap.pRGB, nWidth * nHeight * nBits, 1, fout);

			fclose(fout);
			m_lstInfo.SetCurSel(m_lstInfo.AddString("Capture to \"bitmap.bmp\""));

			// ********************************** 绘制位图***********************
			DWORD count = nWidth * nHeight * nBits;
			unsigned char* buff = new unsigned char[count];
			unsigned char* buff_out = new unsigned char[count];
			//int* buff_out = new int[count];
			unsigned char ImgMax = 0;
			unsigned char ImgMin = 0;
			//ImgMax = ceil(0.9*255) - 20;
			//ImgMin = ceil(0.1*100) + 100;
			ImgMax = 255;
			ImgMin = 100;
			//输入图像每像素字节数,彩色图像为4字节/像素
			int pixelByteIn=4;
			//输入图像每行像素所占字节数,必须是4的倍数
			int lineByteIn=(nWidth*pixelByteIn+ 3)/4*4;     // + 3
			//灰值化后,每像素位数为8比特
			int m_nBitCountOut=8;
			//输出图像每行像素所占字节数,必须是4的倍数
			int lineByteOut=(nWidth*m_nBitCountOut/8+ 3)/4*4;    //  +3   
			int i = 0,j = 0;
			for(i = 0; i < nHeight; ++i)
			{
				memcpy(&buff[i*nWidth*nBits],&(g_config.Channel[nChannel].Bitmap.pRGB[(nHeight - i) * nWidth * nBits]),nWidth * nBits);
			}

			for(i = 0; i < nHeight; ++i)
			{
				for(j = 0; j < nWidth; ++j)
				{
					//根据灰值化公式为输出图像赋值	
					*(buff_out+i*nWidth*nBits/*nWidth应该是lineByteIn */+j)
						=(0.30**(buff+i*nWidth*nBits/*nWidth应该是lineByteIn 以下都应该要改*/+j*pixelByteIn+1)    
						+0.59**(buff+i*nWidth*nBits+j*pixelByteIn+2)
						+0.11**(buff+i*nWidth*nBits+j*pixelByteIn+3)+0.5);     // 转换为灰度图的像素数据   有点问题?求解
					ImgTemp = int(*(buff_out+i*nWidth*nBits+j) - ImgMin);
					//  会不会出错和你使用位图有关,如果位图宽度字节数刚好是4的倍数就不会有问题,否则图像会出现问题
					if (ImgTemp < 0)
					{
						*(buff_out+i*nWidth*nBits+j) = 0;
					}
					else
					{
						ImgTemp = int((abs(*(buff_out+i*nWidth*nBits+j) - ImgMin))/(ImgMax - ImgMin)*255);
						if (ImgTemp > 255)
						{
							*(buff_out+i*nWidth*nBits+j) = 255;
						}
						else
						{
							*(buff_out+i*nWidth*nBits+j) = (abs(*(buff_out+i*nWidth*nBits+j) - ImgMin))/(ImgMax - ImgMin)*255;
						}
					}

				}
			}

			CBitmap bitmap;
			bitmap.CreateBitmap(nWidth ,nHeight ,1,(nBits) * 8,buff_out);

			CWnd* pWnd = GetDlgItem(IDC_SHOW_IMAGE);
			CDC* dc = pWnd->GetDC();
			CDC MemDC;
			MemDC.CreateCompatibleDC(dc);
			MemDC.SelectObject(&bitmap);
			CRect rect;
			pWnd->GetClientRect(&rect);
			dc->SetStretchBltMode(HALFTONE);
			int bmpPro = 1;
			dc->StretchBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,bmpPro*rect.Width(),bmpPro*rect.Height(),SRCCOPY); 
			//dc->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);//显示位图
			//释放RGB缓冲
			delete[] g_config.Channel[nChannel].Bitmap.pRGB;
			g_config.Channel[nChannel].Bitmap.pRGB = NULL;
		}
	}
	return TRUE;
}
pipi20151001 2015-11-07
  • 打赏
  • 举报
回复
第一个红色提示的,是获取对应的颜色位数 第二段,那是根据转灰度的计算公式,建议看看彩色转灰度图的原理。
赵4老师 2015-11-07
  • 打赏
  • 举报
回复
搜“彩色转灰度 源代码”

19,468

社区成员

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

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