前言
圖片處理是開發(fā)過程中經(jīng)常遇到和要處理的問題,畢竟圖片是比較耗系統(tǒng)資源,網(wǎng)絡(luò)資源,存儲空間。。。,因此,圖片的處理顯得格外重要,去百度查閱資料,就會看到很多關(guān)于讀片處理的方法,以及圖片的加載框架,他們都是用來處理圖片的。
常見的圖片處理方式大概有如下幾類。比如圖片的等比縮放,圖片海量加載,圖片的裁剪,圖片的無損壓縮,圖片的旋轉(zhuǎn),圖片實現(xiàn)畫中畫,圖片實現(xiàn)陰影,改變圖片形狀等
然后,這些操作只是符合日常需求開發(fā),如果涉及的高深的算法層面就不太實用,自己在做人臉識別項目中親自體驗常規(guī)處理真的難以解決高難度問題。今天,我介紹一下其他類型的圖片處理算法。首先,我們需要了解倆個概念RGB和ARGB。
01
**RGB和ARGB**
**RGB**
RGB色彩模式使用RGB模型為圖像中每個像素的RGB分量分配一個0~255范圍內(nèi)的強度值。RGB圖像僅僅使用三種顏色,R(red)、G(green)、B(blue),就能夠使它們依照不同的比例混合,在屏幕上呈現(xiàn)16777216(256 * 256 * 256)種顏色。
在電腦中,RGB的所謂“多少”就是指亮度,并使用整數(shù)來表示。通常情況下,RGB各有256級亮度,用數(shù)字表示為從0、1、2…直到255。
**ARGB**
一種色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常見于32位位圖的存儲結(jié)構(gòu)。
ARGB—Alpha,Red,Green,Blue.
知道了這倆個概念,就可以了解更多較深層次的圖片處理算法了。下面我介紹一下自己在做人臉識別中常用到的算法。
02
**灰度化**
在RGB模型中,假設(shè)R=G=B時,則彩色表示一種灰度顏色,當(dāng)中R=G=B的值叫灰度值,因此,灰度圖像每一個像素僅僅需一個字節(jié)存放灰度值(又稱強度值、亮度值),灰度范圍為0-255。一般有下面四種方法對彩色圖像進(jìn)行灰度化,詳細(xì)方法參考csdn大牛博客,講的非常好。
03
**二值化**
一幅圖像包含目標(biāo)物體、背景還有噪聲,要想從多值的數(shù)字圖像中直接提取出目標(biāo)物體,最經(jīng)常使用的方法就是設(shè)定一個全局的閾值T,用T將圖像的數(shù)據(jù)分成兩部分:大于T的像素群和小于T的像素群。將大于T的像素群的像素值設(shè)定為白色(或者黑色),小于T的像素群的像素值設(shè)定為黑色(或者白色)。
比方:計算每個像素的(R+G+B)/3,假設(shè)>127,則設(shè)置該像素為白色,即R=G=B=255;否則設(shè)置為黑色,即R=G=B=0。
簡單實現(xiàn)代碼如下:
{
Bitmap bitImage = new Bitmap(pictureBox1.Image);//二值化pictureBox1中的圖片
Color c;
int height = pictureBox1.Image.Height;
int width = pictureBox1.Image.Width;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
c = bitImage.GetPixel(j,i);
int r = c.R;
int g = c.G;
int b = c.B;
if ((r + g + b) / 3 >= 127)
{
bitImage.SetPixel(j, i, Color.FromArgb(255, 255, 255));
}
else
{
bitImage.SetPixel(j, i, Color.FromArgb(0,0,0));
}
}
}
return bitImage;
}ascript
04
**膨脹算法**
膨脹是將與物體接觸的全部背景點合并到該物體中,使邊界向外部擴張的過程。
能夠用來填補物體中的空洞。
用3x3的結(jié)構(gòu)元素,掃描圖像的每個像素
用結(jié)構(gòu)元素與其覆蓋的二值圖像做“或”操作
假設(shè)都為0,結(jié)果圖像的該像素為0。否則為1
結(jié)果:使二值圖像擴大一圈
膨脹(dilation)能夠看做是腐蝕的對偶運算,其定義是:把結(jié)構(gòu)元素B平移a后得到Ba,若Ba擊中X,我們記下這個a點。全部滿足上述條件的a點組成的集合稱做X被B膨脹的結(jié)果。用公式表示為:D(X)={a | Ba↑X}=X腐蝕,膨脹,細(xì)化算法B,例如以下圖所看到的。圖中X是被處理的對象,B是結(jié)構(gòu)元素,不難知道,對于隨意一個在陰影部分的點a,Ba擊中X,所以X被B膨脹的結(jié)果就是那個陰影部分。陰影部分包含X的全部范圍,就象X膨脹了一圈似的,這就是為什么叫膨脹的原因
![圖片](//file.elecfans.com/web2/M00/8F/3F/poYBAGPjXwWAYVTXAAGdzZEFSiQ676.jpg)
在下圖中,左邊是被處理的圖象X(二值圖象,我們針對的是黑點),中間是結(jié)構(gòu)元素B。膨脹的方法是,拿B的中心點和X上的點及X周圍的點一個一個地對,假設(shè)B上有一個點落在X的范圍內(nèi),則該點就為黑;右邊是膨脹后的結(jié)果。能夠看出,它包含X的全部范圍,就象X膨脹了一圈似的。
![圖片](//file.elecfans.com/web2/M00/8F/C3/pYYBAGPjXwSAY1KwAAOC21wRXiM686.jpg)
我設(shè)計了一個簡單的膨脹算法,依次遍歷整個圖片的像素,分析每個像素的周圍八個像素,僅僅要該像素周圍存在黑色的像素,就設(shè)置該像素顏色為黑色。以下是使用膨脹算法處理經(jīng)過二值化后的圖像的實現(xiàn)代碼:
public bool[] getRoundPixel(Bitmap bitmap, int x, int y)//返回(x,y)周圍像素的情況,為黑色,則設(shè)置為true
{
bool[] pixels=new bool[8];
Color c;
int num = 0;
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
c = bitmap.GetPixel(x+i,y+j);
if (i != 0 || j != 0)
{
if (255 == c.G)//由于經(jīng)過了二值化,所以僅僅要檢查RGB中一個屬性的值
{
pixels[num] = false;//為白色,設(shè)置為false
num++;
}
else if(0==c.G)
{
pixels[num] = true;//為黑色,設(shè)置為true
num++;
}
}
}
}
return pixels;
}
public Bitmap expend()
{
Bitmap bitImage = new Bitmap(pictureBox2.Image);//處理pictureBox2中的圖片
Bitmap bitImage1 = new Bitmap(pictureBox2.Image);
int height = pictureBox1.Image.Height;
int width = pictureBox1.Image.Width;
bool[] pixels;
for (int i = 1; i < width-1; i++)
{
for (int j = 1; j < height-1; j++)
{
if (bitImage.GetPixel(i, j).R != 0)
{
pixels = getRoundPixel(bitImage, i, j);
for (int k = 0; k < pixels.Length; k++)
{
if (pixels[k] == true)
{
//set this piexl's color to black
bitImage1.SetPixel(i, j, Color.FromArgb(0,0,0));
break;
}
}
}
}
}
return bitImage1;
}
看看最終執(zhí)行的效果圖如下:
![圖片](//file.elecfans.com/web2/M00/8F/3F/poYBAGPjXwSABNzVAAAFQ6yAYyI591.jpg)
-
圖像處理
+關(guān)注
關(guān)注
27文章
1299瀏覽量
56837 -
RGB
+關(guān)注
關(guān)注
4文章
801瀏覽量
58626
發(fā)布評論請先 登錄
相關(guān)推薦
評論