• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Dict.CN 在線詞典, 英語(yǔ)學(xué)習(xí), 在線翻譯

            學(xué)海苦作舟,書山勤為徑

            留下點(diǎn)回憶

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            Denoise

            English study

            Web技術(shù)

            數(shù)據(jù)壓縮

            一些連接

            最新評(píng)論

            如何將真彩色圖轉(zhuǎn)換為各種灰度圖

            首先來看一下彩色圖和灰度圖的特點(diǎn)。

            在計(jì)算機(jī)中使用最多的 RGB 彩色空間,分別對(duì)應(yīng)紅、綠、藍(lán)三種顏色;通過調(diào)配三個(gè)分量的比例來組成各種顏色。一般可以使用 1 2 4 8 16 24 32 位來存儲(chǔ)這三顏色,不過現(xiàn)在一個(gè)分量最大是用 8 位來表示,最大值是 255 ,對(duì)于 32 位的顏色,高 8 位是用來表示通明度的。彩色圖一般指 16 位以上的圖。灰度圖有一個(gè)特殊之處就是組成顏色的三個(gè)分量相等;而一般灰度圖是 8 位以下。

            在彩色電視機(jī)系統(tǒng)中,通常使用一種叫 YUV 的色彩空間,其中 Y 表示亮度信號(hào);也就是這個(gè) YUV 空間解決了彩色電視機(jī)和黑白電視機(jī)的兼容問題。

            對(duì)于人眼來說,亮度信號(hào)是最敏感的,如果將彩色圖像轉(zhuǎn)換為灰度圖像,僅僅需要轉(zhuǎn)換保存亮度信號(hào)就可以。

            RGB YUV 空間的 Y 轉(zhuǎn)換公式為:

            Y = 0.299R+0.587G+0.114B

            ?

            WINDOWS 中,表示 16 位以上的圖和以下的圖有點(diǎn)不同; 16 位以下的圖使用一個(gè)調(diào)色板來表示選擇具體的顏色,調(diào)色板的每個(gè)單元是 4 個(gè)字節(jié),其中一個(gè)透明度;而具體的像素值存儲(chǔ)的是索引,分別是 1 2 4 8 位。 16 位以上的圖直接使用像素表示顏色。

            ?

            那么如何將彩色圖轉(zhuǎn)換為灰度圖呢?

            灰度圖中有調(diào)色板,首先需要確定調(diào)色板的具體顏色取值。我們前面提到了,灰度圖的三個(gè)分量相等。

            當(dāng)轉(zhuǎn)換為 8 位的時(shí)候,調(diào)色板中有 256 個(gè)顏色,每個(gè)正好從 0 255 個(gè),三個(gè)分量都相等。

            當(dāng)轉(zhuǎn)換為 4 位的時(shí)候,調(diào)色板中 16 個(gè)顏色,等間隔平分 255 個(gè)顏色值,三個(gè)分量都相等。

            當(dāng)轉(zhuǎn)換為 2 位的時(shí)候,調(diào)色板中 4 個(gè)顏色,等間隔平分 255 個(gè)顏色,三個(gè)分量相等。

            當(dāng)轉(zhuǎn)換為 1 位的時(shí)候,調(diào)色板中兩個(gè)顏色,是 0 255 ,表示黑和白。

            ?

            將彩色轉(zhuǎn)換為灰度時(shí)候,按照公式計(jì)算出對(duì)應(yīng)的值,該值實(shí)際上是亮度的級(jí)別;亮度從 0 255 ;由于不同的位有不同的亮度級(jí)別,所以 Y 的具體取值如下:

            ?????? Y = Y/ (1<<(8- 轉(zhuǎn)換的位數(shù) ));

            ?

            最后一點(diǎn)需要注意,得到 Y 值存放方式是不同的;分別用對(duì)應(yīng)的位數(shù)來存儲(chǔ)對(duì)應(yīng)的 Y 值。

            ?

            這里是代碼片段:

            計(jì)算調(diào)色板和 Y 的值代碼。

            ??1 LPBYTE??CColorDeepChange::ConvertTo8Gray(LPBYTE?lpByte,?
            ??2
            ??3 ????????????????????????????????????????? int ?width,?
            ??4
            ??5 ????????????????????????????????????????? int ?height,?
            ??6
            ??7 ?????????????????????????????????????????DWORD? & dwGraySize,?
            ??8
            ??9 ????????????????????????????????????????? int ?nToBit)?
            ?10
            ?11 {?
            ?12
            ?13 ????DWORD???nRowLen? = ???TS_4BYTESALIGN(width * nToBit);?
            ?14
            ?15 ????DWORD???nColorTableSize? = ?(( 1 << nToBit) * sizeof (RGBQUAD));?
            ?16
            ?17 ????DWORD???nColorNum? = ? 1 << nToBit;?
            ?18
            ?19 ????dwGraySize? = ????nRowLen * height + nColorTableSize;?
            ?20
            ?21 ????LPBYTE??lpNewImgBuf? = ?NULL;?
            ?22
            ?23 ????BYTE????r,g,b;?
            ?24
            ?25 ???? float ???y;?
            ?26
            ?27 ????
            ?28
            ?29 ????lpNewImgBuf? = ? new ?BYTE[dwGraySize];?
            ?30
            ?31 ????LPBYTE??lpPixels? = ?(LPBYTE)(lpNewImgBuf? + nColorTableSize);?
            ?32
            ?33 ????LPRGBQUAD???lpvColorTable = (LPRGBQUAD)lpNewImgBuf;?
            ?34
            ?35 ????memset(lpNewImgBuf, 0 ,dwGraySize);?
            ?36
            ?37 ??
            ?38
            ?39 ???? for ( int ?i? = ? 0 ;i < nColorNum;i ++ )?
            ?40
            ?41 ???? {?
            ?42
            ?43 ???????? if (nToBit? == ? 8 )?
            ?44
            ?45 ???????? {?
            ?46
            ?47 ????????????( * (lpvColorTable)).rgbBlue = (BYTE)i;?
            ?48
            ?49 ????????????( * (lpvColorTable)).rgbGreen = (BYTE)i;?
            ?50
            ?51 ????????????( * (lpvColorTable)).rgbRed = (BYTE)i;?
            ?52
            ?53 ????????}
            ?
            ?54
            ?55 ???????? else ? if (nToBit? == ? 4 )?
            ?56
            ?57 ???????? {?
            ?58
            ?59 ????????????( * (lpvColorTable)).rgbBlue = (BYTE)(i << ( 8 - nToBit)) + i;?
            ?60
            ?61 ????????????( * (lpvColorTable)).rgbGreen = (BYTE)(i << ( 8 - nToBit)) + i;?
            ?62
            ?63 ????????????( * (lpvColorTable)).rgbRed = (BYTE)(i << ( 8 - nToBit)) + i;?
            ?64
            ?65 ????????}
            ?
            ?66
            ?67 ???????? else ? if (nToBit? == ? 2 )?
            ?68
            ?69 ???????? {?
            ?70
            ?71 ????????????( * (lpvColorTable)).rgbBlue = (BYTE)( 255 / 3 ) * i;?
            ?72
            ?73 ????????????( * (lpvColorTable)).rgbGreen = (BYTE)( 255 / 3 ) * i;?
            ?74
            ?75 ????????????( * (lpvColorTable)).rgbRed = (BYTE)( 255 / 3 ) * i;?
            ?76
            ?77 ????????}
            ?
            ?78
            ?79 ???????? else ? if (nToBit? == ? 1 )?
            ?80
            ?81 ???????? {?
            ?82
            ?83 ????????????( * (lpvColorTable)).rgbBlue = (BYTE) 255 * i;?
            ?84
            ?85 ????????????( * (lpvColorTable)).rgbGreen = (BYTE) 255 * i;?
            ?86
            ?87 ????????????( * (lpvColorTable)).rgbRed = (BYTE) 255 * i;?
            ?88
            ?89 ????????}
            ?
            ?90
            ?91 ??
            ?92
            ?93 ????????( * (lpvColorTable)).rgbReserved = 0 ;?
            ?94
            ?95 ????????lpvColorTable ++ ;?
            ?96
            ?97 ????}
            ?
            ?98
            ?99 ??
            100
            101 ????LPBYTE??lpOldImage? = ?lpByte;?
            102
            103 ????LPBYTE??lpTempPixel? = ?lpPixels;?
            104
            105 ???? int ?loops?? = ? 0 ;?
            106
            107 ???? int ?nStop? = ? 0 ;?
            108
            109 ???? for ( long ??h = 0 ;h < height;h ++ )?
            110
            111 ???? {?
            112
            113 ???????? for ( long ??w = 0 ;w < width;w ++ )?
            114
            115 ???????? {???
            116
            117 ????????????b = (unsigned??? char )( * lpOldImage ++ );?
            118
            119 ????????????g = (unsigned??? char )( * lpOldImage ++ );?
            120
            121 ????????????r = (unsigned??? char )( * lpOldImage ++ );?
            122
            123 ??
            124
            125 ????????????y = ( float )(r * 0.299 + g * 0.587 + b * 0.114 )?;?
            126
            127 ????????????BYTE?bVal? = ?(BYTE)y >> ( 8 - nToBit);?
            128
            129 ????????????SetPixelValueByBits(lpTempPixel,nToBit,loops,(BYTE)bVal);?
            130
            131 ???????????? // ErrorDiffuse(lpPixels,nToBit,loops,((int)y)?-?(bVal<<(8-nToBit)),?
            132
            133 ???????????? // ??????????????????????w,h,nRowLen,dwGraySize-nColorTableSize);?
            134
            135 ????????}
            ???
            136
            137 ????}
            ?
            138
            139 ??
            140
            141 ???? return ?lpNewImgBuf;?
            142
            143 }
            ?
            144
            145

            下面是設(shè)置像素值的代碼:

            ??1 void ???CColorDeepChange::SetPixelValueByBits(LPBYTE? & lpByte, int ?nBits, int ? & loops,BYTE?value)?
            ??2
            ??3 {?
            ??4
            ??5 ???? switch (nBits)?
            ??6
            ??7 ???? {?
            ??8
            ??9 ???? case ? 8 :?
            ?10
            ?11 ??????? * (lpByte ++ ) = value;?
            ?12
            ?13 ??????? break ;?
            ?14
            ?15 ???? case ? 4 :?
            ?16
            ?17 ??????? {?
            ?18
            ?19 ??????????? if (loops)?
            ?20
            ?21 ??????????? {?
            ?22
            ?23 ??????????????loops? = ? 0 ;?
            ?24
            ?25 ??????????????BYTE?bVal? = ?( * lpByte) & 0xF0 ;?
            ?26
            ?27 ??????????????value? &= ? 0x0F ;?
            ?28
            ?29 ??????????????bVal? = (bVal >> 4 ) + value;?
            ?30
            ?31 ??????????????? if (bVal > 0x0F )?bVal? = ? 0x0F ;?
            ?32
            ?33 ??????????????( * lpByte)? <<= ? 4 ;?
            ?34
            ?35 ??????????????( * lpByte)? += ?bVal;?
            ?36
            ?37 ??????????????lpByte ++ ;?
            ?38
            ?39 ???????????}
            ?
            ?40
            ?41 ??????????? else ?
            ?42
            ?43 ??????????? {?
            ?44
            ?45 ??????????????value? &= ? 0x0F ;?
            ?46
            ?47 ??????????????( * lpByte)? += ?value;?
            ?48
            ?49 ?????????????? if (( * lpByte) > 0x0F )?( * lpByte)? = ? 0x0F ;?
            ?50
            ?51 ??????????????loops? = 1 ;?
            ?52
            ?53 ???????????}
            ?
            ?54
            ?55 ???????}
            ?
            ?56
            ?57 ??????? break ;?
            ?58
            ?59 ???? case ? 2 :?
            ?60
            ?61 ??????? {?
            ?62
            ?63 ???????????value? &= ? 0x03 ;?
            ?64
            ?65 ???????????( * lpByte)? += ?value;?
            ?66
            ?67 ??????????? if (loops? != ? 3 )?
            ?68
            ?69 ??????????? {?
            ?70
            ?71 ??????????????( * lpByte)? <<= ? 2 ;?
            ?72
            ?73 ??????????????loops ++ ;?
            ?74
            ?75 ???????????}
            ?
            ?76
            ?77 ??????????? else ?
            ?78
            ?79 ??????????? {?
            ?80
            ?81 ??????????????loops? = 0 ;?
            ?82
            ?83 ??????????????lpByte ++ ;?
            ?84
            ?85 ???????????}
            ?
            ?86
            ?87 ???????}
            ?
            ?88
            ?89 ??????? break ;?
            ?90
            ?91 ???? case ? 1 :?
            ?92
            ?93 ??????? {?
            ?94
            ?95 ???????????value? &= ? 0x01 ;?
            ?96
            ?97 ???????????( * lpByte)? += ?value;?
            ?98
            ?99 ??????????? if (loops? != ? 7 )?
            100
            101 ??????????? {?
            102
            103 ??????????????( * lpByte)? <<= ? 1 ;?
            104
            105 ??????????????loops ++ ;?
            106
            107 ???????????}
            ?
            108
            109 ??????????? else ?
            110
            111 ??????????? {?
            112
            113 ??????????????loops? = 0 ;?
            114
            115 ??????????????lpByte ++ ;?
            116
            117 ???????????}
            ?
            118
            119 ???????}
            ?
            120
            121 ??????? break ;?
            122
            123 ????}
            ?
            124
            125 }
            ?
            126

            ?

            有一點(diǎn)需要說明的:

            在計(jì)算 Y 值的時(shí)候,使用的整數(shù)除法,這是有誤差的,為了消除誤差,需要采用誤差擴(kuò)散的算法,也就是將該誤差值向其鄰近的想素點(diǎn)擴(kuò)散,當(dāng)然按照一定的比例來分配;例如:整除之后,余數(shù)是 5 ,采用 3/2/3 的策略,就是,右邊像素和正下面的像素各占 3/8 ,而右下角的像素占 2/8 。在這方面我發(fā)現(xiàn) ACDSEE 做的很好,其圖像的漸進(jìn)做的很好。

            源碼下載:ImageConvert.zip

            posted on 2006-07-27 21:00 笨笨 閱讀(13965) 評(píng)論(3)  編輯 收藏 引用

            評(píng)論

            # re: 如何將真彩色圖轉(zhuǎn)換為各種灰度圖 2010-04-23 09:38 icegrape

            詢問一下:
            對(duì)于一幅數(shù)字圖像,每個(gè)像素所包含的信息是什么?
            顯示器顯示圖像時(shí),加在顯像管或者液晶屏上的數(shù)據(jù)信號(hào)是電壓信號(hào)嗎?這個(gè)信號(hào)如何轉(zhuǎn)化為帶有色彩和亮度的點(diǎn)?  回復(fù)  更多評(píng)論   

            # re: 如何將真彩色圖轉(zhuǎn)換為各種灰度圖 2011-03-18 19:40 Dom

            Very good, and thank you for this paper.  回復(fù)  更多評(píng)論   

            # re: 如何將真彩色圖轉(zhuǎn)換為各種灰度圖 2012-03-20 15:58

            DWORD nRowLen = TS_4BYTESALIGN(width * nToBit);
            什么意思?TS_4BYTESALIGN這個(gè)函數(shù)什么意思?  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            男女久久久国产一区二区三区| 午夜久久久久久禁播电影| 伊人色综合九久久天天蜜桃| 亚洲愉拍99热成人精品热久久| 久久91精品国产91久久麻豆| 久久综合久久综合亚洲| 国产精品久久自在自线观看| 亚洲午夜精品久久久久久浪潮| 精品无码久久久久久尤物| 一本久久免费视频| 91精品国产综合久久四虎久久无码一级 | 久久青青草原精品国产| 久久夜色精品国产亚洲av| 国产成人久久激情91| 精品国产99久久久久久麻豆 | 狠狠色婷婷综合天天久久丁香 | 久久精品亚洲AV久久久无码| 亚洲国产精品婷婷久久| 亚洲午夜久久久久妓女影院 | 久久精品无码一区二区WWW| 久久se这里只有精品| 91久久婷婷国产综合精品青草| 久久国产AVJUST麻豆| 精品久久久久久久久久中文字幕| 久久久久亚洲Av无码专| 色欲综合久久中文字幕网| 久久久久国产精品人妻| 久久久国产视频| 一级A毛片免费观看久久精品| 久久人搡人人玩人妻精品首页 | 久久久午夜精品福利内容| 久久99精品国产麻豆不卡| 亚洲一区二区三区日本久久九| 狠狠色丁香久久婷婷综| 国产情侣久久久久aⅴ免费| 久久人人爽爽爽人久久久| 亚洲精品tv久久久久久久久| 性色欲网站人妻丰满中文久久不卡| 久久久亚洲AV波多野结衣| 一本一道久久综合狠狠老| 无码精品久久久久久人妻中字|