画像の簡易誤差拡散法による2階調化

解説

 画像をグレースケール変換して指定されたしきい値を境に2つの色に変える。そのとき 新しい画像と元画像との誤差を右のピクセルに反映させる簡易的な誤差拡散法を採用した。



実行例

 以下のコードで処理を施した。
		RGBTRIPLE	rgbHigh;
		RGBTRIPLE	rgbLow;

		rgbHigh.rgbtBlue	= 100;
		rgbHigh.rgbtGreen	= 255;
		rgbHigh.rgbtRed		= 255;
		rgbLow.rgbtBlue		= 0;
		rgbLow.rgbtGreen	= 0;
		rgbLow.rgbtRed		= 0;
		_cImage2.BicolorErrorVarianceEasy(120,rgbHigh,rgbLow);






ソースコード

 GDI+を利用した画像処理テストのスケルトン2を 元に拡張する。


 前に作成した「DnpImage.h」に2階調化関数を追加する。


class	CDnpImage : public CDnpImageBase
	,public CDnpImageConvolution
	,public CDnpColorSpaceHLS
	,public CDnpColorSpaceHSV
{
public:

	//
	//	画像の簡易誤差拡散法による2階調化
	//
	//グレースケール変換したときの色値がcbThresholdを超えていればrgbHighに、
	//下回ればrgbLowに変えて2階調化する。新しい値の誤差を次にピクセルに割り
	//振る単純な誤差拡散法による
	//
	bool	BicolorErrorVarianceEasy(BYTE cbThreshold,RGBTRIPLE rgbHigh,RGBTRIPLE rgbLow)
	{
		if(IsValidImage() == false)
			return	false;

		int			nStrideBytes;
		bool		ret;
		UINT		x;
		UINT		y;
		UINT		nWidth;
		UINT		nHeight;
		BYTE*		pData;
		RGBTRIPLE*	pRGB;
		BYTE		cbHigh;
		BYTE		cbLow;
		int			nError;

		cbHigh	= (BYTE)((77 * rgbHigh.rgbtRed + 150 * rgbHigh.rgbtGreen + 29 * rgbHigh.rgbtBlue) >> 8);
		cbLow	= (BYTE)((77 * rgbLow .rgbtRed + 150 * rgbLow .rgbtGreen + 29 * rgbLow .rgbtBlue) >> 8);

		nWidth	= GetWidth();
		nHeight	= GetHeight();

		ret = LockBits(&pData,&nStrideBytes);
		if(ret == false)
			return	false;

		for(y = 0; y < nHeight; y++)
		{
			nError = 0;
			pRGB = (RGBTRIPLE*)pData;
			for(x = 0; x < nWidth; x++)
			{
				int		nTmp;

				nTmp = (BYTE)((77 * pRGB[x].rgbtRed + 150 * pRGB[x].rgbtGreen + 29 * pRGB[x].rgbtBlue) >> 8);
				nTmp -= nError;
				if(nTmp > 255)
					nTmp = 255;
				if(nTmp < 0)
					nTmp = 0;

				if(nTmp > (int)cbThreshold)
				{
					pRGB[x] = rgbHigh;
					nError = cbHigh - nTmp;
				}
				else
				{
					pRGB[x] = rgbLow;
					nError = cbLow - nTmp;
				}
				if(nError > 255)
					nError = 255;
				if(nError < 0)
					nError = 0;
			}
			pData += nStrideBytes;
		}
		UnlockBits();

		return	true;
	}



	。。。。省略。。。。

};

カテゴリー「VC++ TIPS」 のエントリー