﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-水蔚如蓝-文章分类-VC++学习</title><link>http://www.cppblog.com/mineralized/category/2796.html</link><description>C++学习者</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 03:02:10 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 03:02:10 GMT</pubDate><ttl>60</ttl><item><title>图像二值化算法</title><link>http://www.cppblog.com/mineralized/articles/13560.html</link><dc:creator>晴天没云</dc:creator><author>晴天没云</author><pubDate>Wed, 11 Oct 2006 02:52:00 GMT</pubDate><guid>http://www.cppblog.com/mineralized/articles/13560.html</guid><wfw:comment>http://www.cppblog.com/mineralized/comments/13560.html</wfw:comment><comments>http://www.cppblog.com/mineralized/articles/13560.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mineralized/comments/commentRss/13560.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mineralized/services/trackbacks/13560.html</trackback:ping><description><![CDATA[
		<div>/*************************************************************************<br /> *<br /> * 函数名称：<br /> *   ThresholdDIB()<br /> *<br /> * 参数:<br /> *   LPSTR lpDIBBits    - 指向源DIB图像指针<br /> *   LONG  lWidth       - 源图像宽度（象素数）<br /> *   LONG  lHeight      - 源图像高度（象素数）<br /> *<br /> * 返回值:<br /> *   BOOL               - 运算成功返回TRUE，否则返回FALSE。<br /> *<br /> * 说明:<br /> * 该函数用于对图像进行阈值分割运算。<br /> * <br /> ************************************************************************/</div>
		<br />
		<div>BOOL WINAPI ThresholdDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)<br />{<br /> <br /> // 指向源图像的指针<br /> LPSTR lpSrc;<br /> <br /> // 指向缓存图像的指针<br /> LPSTR lpDst;<br /> <br /> // 指向缓存DIB图像的指针<br /> LPSTR lpNewDIBBits;<br /> HLOCAL hNewDIBBits;</div>
		<br />
		<div> //循环变量<br /> long i;<br /> long j;</div>
		<br />
		<div> //像素值<br /> unsigned char pixel;</div>
		<br />
		<div> //直方图数组<br /> long lHistogram[256];</div>
		<br />
		<div> //阈值，最大灰度值与最小灰度值，两个区域的平均灰度值<br /> unsigned char iThreshold,iNewThreshold,iMaxGrayValue,iMinGrayValue,iMean1GrayValue,iMean2GrayValue;</div>
		<br />
		<div> //用于计算区域灰度平均值的中间变量<br /> long lP1,lP2,lS1,lS2;</div>
		<br />
		<div> //迭代次数<br /> int iIterationTimes;</div>
		<br />
		<div> // 图像每行的字节数<br /> LONG lLineBytes;</div>
		<br />
		<div> // 暂时分配内存，以保存新图像<br /> hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);</div>
		<br />
		<div> if (hNewDIBBits == NULL)<br /> {<br />  // 分配内存失败<br />  return FALSE;<br /> }<br /> <br /> // 锁定内存<br /> lpNewDIBBits = (char * )LocalLock(hNewDIBBits);</div>
		<br />
		<div> // 初始化新分配的内存，设定初始值为255<br /> lpDst = (char *)lpNewDIBBits;<br /> memset(lpDst, (BYTE)255, lWidth * lHeight);</div>
		<br />
		<div> // 计算图像每行的字节数<br /> lLineBytes = WIDTHBYTES(lWidth * 8);</div>
		<br />
		<div> for (i = 0; i &lt; 256;i++)<br /> {<br />  lHistogram[i]=0;<br /> }</div>
		<br />
		<div> //获得直方图<br /> iMaxGrayValue = 0;<br /> iMinGrayValue = 255;<br /> for (i = 0;i &lt; lWidth ;i++)<br /> {<br />  for(j = 0;j &lt; lHeight ;j++)<br />  {<br />   // 指向源图像倒数第j行，第i个象素的指针   <br />   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;<br /> <br />   pixel = (unsigned char)*lpSrc;<br />   <br />   lHistogram[pixel]++;<br />   //修改最大，最小灰度值<br />   if(iMinGrayValue &gt; pixel)<br />   {<br />    iMinGrayValue = pixel;<br />   }<br />   if(iMaxGrayValue &lt; pixel)<br />   {<br />    iMaxGrayValue = pixel;<br />   }<br />  }<br /> }</div>
		<br />
		<div> //迭代求最佳阈值<br /> iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;<br /> iThreshold = 0;<br /> <br /> for(iIterationTimes = 0; iThreshold != iNewThreshold &amp;&amp; iIterationTimes &lt; 100;iIterationTimes ++)<br /> {<br />  iThreshold = iNewThreshold;<br />  lP1 =0;<br />  lP2 =0;<br />  lS1 = 0;<br />  lS2 = 0;<br />  //求两个区域的灰度平均值<br />  for (i = iMinGrayValue;i &lt; iThreshold;i++)<br />  {<br />   lP1 += lHistogram[i]*i;<br />   lS1 += lHistogram[i];<br />  }<br />  iMean1GrayValue = (unsigned char)(lP1 / lS1);<br />  for (i = iThreshold+1;i &lt; iMaxGrayValue;i++)<br />  {<br />   lP2 += lHistogram[i]*i;<br />   lS2 += lHistogram[i];<br />  }<br />  iMean2GrayValue = (unsigned char)(lP2 / lS2);<br />  iNewThreshold =  (iMean1GrayValue + iMean2GrayValue)/2;<br /> }</div>
		<br />
		<div> //根据阈值将图像二值化<br /> for (i = 0;i &lt; lWidth ;i++)<br /> {<br />  for(j = 0;j &lt; lHeight ;j++)<br />  {<br />   // 指向源图像倒数第j行，第i个象素的指针   <br />   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;<br /> <br />   // 指向目标图像倒数第j行，第i个象素的指针   <br />   lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;</div>
		<br />
		<div>   pixel = (unsigned char)*lpSrc;<br />   <br />   if(pixel &lt;= iThreshold)<br />   {<br />    *lpDst = (unsigned char)0;<br />   }<br />   else<br />   {<br />    *lpDst = (unsigned char)255;<br />   }<br />  }<br /> }</div>
		<br />
		<div> // 复制图像<br /> memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);</div>
		<br />
		<div> // 释放内存<br /> LocalUnlock(hNewDIBBits);<br /> LocalFree(hNewDIBBits);</div>
		<br />
		<div> // 返回<br /> return TRUE;<br />}</div>
<img src ="http://www.cppblog.com/mineralized/aggbug/13560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mineralized/" target="_blank">晴天没云</a> 2006-10-11 10:52 <a href="http://www.cppblog.com/mineralized/articles/13560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>