📄 chap04.htm
字号:
</span>
15,47,7,39,13,45,5,37,</p>
<p style='line-height:18.0pt'><span>
</span>
63,31,55,23,61,29,53,21};</p>
<p style='line-height:18.0pt'><span lang=EN-US>BOOL LimbPatternM3(HWND hWnd)</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>{</span></p>
<p style='line-height:18.0pt'>DWORD
OffBits,BufSize</p>
<p style='line-height:18.0pt'>LPBITMAPINFOHEADER lpImgData;</p>
<p style='line-height:18.0pt'>LPSTR
lpPtr;</p>
<p style='line-height:18.0pt'>HLOCAL
hTempImgData;</p>
<p style='line-height:18.0pt'>LPBITMAPINFOHEADER lpTempImgData;</p>
<p style='line-height:18.0pt'>LPSTR
lpTempPtr;</p>
<p style='line-height:18.0pt'>HDC
hDc;</p>
<p style='line-height:18.0pt'>HFILE
hf;</p>
<p style='line-height:18.0pt'>LONG
x,y;</p>
<p style='line-height:18.0pt'>unsigned char
num;</p>
<p style='line-height:18.0pt'><span
lang=EN-US>OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>BufSize=OffBits+bi.biHeight*LineBytes;//</span><span
style='font-family:宋体;"Times New Roman"'>要开的缓冲区大小</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>{</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>MessageBox(hWnd,"Error alloc memory!","Error
Message",MB_OK|</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>MB_ICONEXCLAMATION);</span></p>
<p style='line-height:18.0pt'><span> </span>return FALSE;</p>
<p style='line-height:18.0pt'><span
lang=EN-US>}</span></p>
<p style='line-height:18.0pt'>lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
</p>
<p style='line-height:18.0pt'><span
lang=EN-US>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
"Times New Roman"'>拷贝头信息和位图数据</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>memcpy(lpTempImgData,lpImgData,BufSize);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>for(y=0;y<bi.biHeight;y++){</span></p>
<p style='line-height:18.0pt'><span> </span>//lpPtr<span
style='font-family:宋体;"Times New Roman"'>为指向原图位图数据的指针</span></p>
<p style='line-height:18.0pt'><span> </span>lpPtr=(char
*)lpImgData+(BufSize-LineBytes-y*LineBytes);</p>
<p style='line-height:18.0pt'><span> </span>//lpTempPtr<span
style='font-family:宋体;"Times New Roman"'>为指向新图位图数据的指针</span></p>
<p style='line-height:18.0pt'><span> </span>lpTempPtr=(char
*)lpTempImgData+(BufSize-LineBytes-y*LineBytes);</p>
<p style='line-height:18.0pt'><span> </span>for(x=0;x<bi.biWidth;x++){</p>
<p style='line-height:18.0pt'><span>
</span>num=(unsigned char)*lpPtr++;</p>
<p style='line-height:18.0pt'><span>
</span>if ( (num>>2) > BayerPattern[y&7][x&7]) //<span
style='font-family:宋体;"Times New Roman"'>右移两位后做比较</span></p>
<p style='line-height:18.0pt'><span>
</span> *(lpTempPtr++)=(unsigned char)255;
//<span style='font-family:宋体;
"Times New Roman"'>打白点</span></p>
<p style='line-height:18.0pt'><span>
</span>else *(lpTempPtr++)=(unsigned char)0; //<span style='font-family:宋体;
"Times New Roman"'>打黑点</span></p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span
lang=EN-US>}</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>if(hBitmap!=NULL)</span></p>
<p style='line-height:18.0pt'><span> </span>DeleteObject(hBitmap);</p>
<p style='line-height:18.0pt'>hDc=GetDC(hWnd); </p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
"Times New Roman"'>形成新的位图</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LONG)CBM_INIT,</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LPSTR)lpTempImgData+</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>sizeof(BITMAPINFOHEADER)+</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>NumColors*sizeof(RGBQUAD),</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LPBITMAPINFO)lpTempImgData,</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>DIB_RGB_COLORS);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>hf=_lcreat("c:\\limbm3.bmp",0);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); </span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>_lwrite(hf,(LPSTR)lpTempImgData,BufSize);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>_lclose(hf);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
"Times New Roman"'>释放内存和资源</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>ReleaseDC(hWnd,hDc);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>LocalUnlock(hTempImgData);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>LocalFree(hTempImgData);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>GlobalUnlock(hImgData);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>return TRUE;</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>}</span><span
lang=EN-US style='font-size:9.0pt;'></span></p>
<h2> <span
lang=EN-US>4.2</span> <span lang=EN-US> </span><a name="_Toc486331879"></a><a
name="_Toc486332879"></a><a name="_Toc486338988"></a><a name="_Toc454810853"></a><a
name="_Toc454856627"><span><span>抖动法</span></span></a></h2>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>让我们考虑更坏的情况:即使使用了图案化技术,仍然得不到要求的灰度级别。举例说明:假设有一幅</span><span
lang=EN-US>600</span><span style='font-family:宋体;
"Times New Roman"'>×</span><span lang=EN-US>450</span><span
style='font-family:宋体;"Times New Roman"'>×</span><span lang=EN-US>8bit</span><span style='font-family:
宋体;"Times New Roman"'>的灰度图,当用分辨率为</span><span
lang=EN-US>300dpi</span><span style='font-family:宋体;
"Times New Roman"'>×</span><span lang=EN-US>300dpi</span><span
style='font-family:宋体;"Times New Roman"'>的激光打印机将其打印到</span><span lang=EN-US>8</span><span
style='font-family:宋体;"Times New Roman"'>×</span><span lang=EN-US>6</span><span style='font-family:
宋体;"Times New Roman"'>英寸的纸上时,每个象素可以用</span><span
lang=EN-US>(2400/600)</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>×</span><span
lang=EN-US>(1800/450)=4</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>×</span><span
lang=EN-US>4</span><span style='font-family:宋体;
"Times New Roman"'>个点大小的图案来表示,最多能表示</span><span
lang=EN-US>17</span><span style='font-family:宋体;
"Times New Roman"'>级灰度,无法满足</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>级灰度的要求。可有两种解决方案:</span><span lang=EN-US>(1)</span><span
style='font-family:宋体;"Times New Roman"'>减小图象尺寸,由</span><span lang=EN-US>600</span><span
style='font-family:宋体;"Times New Roman"'>×</span><span lang=EN-US>450</span><span style='font-family:
宋体;"Times New Roman"'>变为</span><span
lang=EN-US>150</span><span style='font-family:宋体;
"Times New Roman"'>×</span><span lang=EN-US>113</span><span
style='font-family:宋体;"Times New Roman"'>;</span><span lang=EN-US>(2)</span><span style='font-family:
宋体;"Times New Roman"'>降低图象灰度级,由</span><span
lang=EN-US>256</span><span style='font-family:宋体;
"Times New Roman"'>级变成</span><span lang=EN-US>16</span><span
style='font-family:宋体;"Times New Roman"'>级。这两种方案都不理想。这时,我们就可以采用“抖动法”</span><span lang=EN-US>(dithering)</span><span
style='font-family:宋体;"Times New Roman"'>的技术来解决这个问题。其实刚才给出的算法就是一种抖动算法,称为规则抖动</span><span lang=EN-US>(regular
dithering)</span><span style='font-family:宋体;
"Times New Roman"'>。规则抖动的优点是算法简单;缺点是图案化有时很明显,这是因为取模运算虽然引入了随机成分,但还是有规律的。另外,点之间进行比较时,只要比标准图案上点的值大就打白点,这种做法并不理想,因为,如果当标准图案点的灰度值本身就很小,而图象中点的灰度只比它大一点儿时,图象中的点更接近黑色,而不是白色。一种更好的方法是将这个误差传播到邻近的象素。</span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>下面介绍的</span><span lang=EN-US>Floyd-Steinberg</span><span
style='font-family:宋体;"Times New Roman"'>算法就采用了这种方案。</span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>假设灰度级别的范围从</span><span lang=EN-US>b(black)</span><span
style='font-family:宋体;"Times New Roman"'>到</span><span lang=EN-US>w(white)</span><span
style='font-family:宋体;"Times New Roman"'>,中间值</span><span lang=EN-US>t</span><span style='font-family:
宋体;"Times New Roman"'>为</span><span
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -