[EmguCV|C#]使用EmguCV的DenseHistogram類別計算與紀錄圖像直方圖-直方圖(Histogram)系列(2)
来源:互联网 发布:梦里花落知多少李茉莉 编辑:程序博客网 时间:2024/06/15 21:30
http://www.dotblogs.com.tw/v6610688/archive/2013/12/21/emgucv_calculate_histogram_by_densehistogram.aspx
前言
在前篇,提到了我們在做影像處理時會需要擁有影像的直方圖色彩分布資料,來做一些運算,例如:反投影來比對兩張圖象的色彩分布相似度,並且過濾掉不太可能相似的圖像等
在這篇,我們會使用到EmguCV所提供的專門處理直方圖相關工作的DenseHistogram類別
直方圖介紹
直方圖說穿了其實就是資料的統計圖而已,而在影像上常被用來做色彩分布的統計用。
縱軸我們稱它為樣本數量,橫軸則是樣本的屬性值(例如要計算的屬性是抵達的分鐘),縱軸則代表可能抵達的次數)
而在色彩分布上,橫軸是像素點的數值(從0 – 255 ),縱軸則是像素值在這張影像上各有多少一樣的像素點的總值
或許有人會好奇「直方圖」與「長條圖」的差異在哪裡,其中直方圖的的資料是「是連續的」,所以橫軸的數值會是連續的,有一個順序姓
長條圖則是不連續的(又稱類別資料),橫軸的類別只有相同或不同的關聯,沒有順序性(如下是各國國家的類別)
使用EmguCV的DenseHistorgam計算直方圖
這邊我們程式中使用到的loadImg變數是前一個文章所定義EmguCV保存圖片的資料結構
以下這段程式碼
01
private
DenseHistogram CalHistBlue()
02
{
03
//計算Blue單通道
04
int
Bbin = 8;
//切割量化的數量
05
RangeF BRange =
new
RangeF(0,255);
06
DenseHistogram blueHist =
new
DenseHistogram(Bbin, BRange);
07
//參數一是要計算的顏色資料,這邊分割通道並取得Blue通道的顏色;依序[1]:Green->[2]:Red
08
blueHist.Calculate(
new
IImage[] { loadImg.Split()[0] },
false
,
null
);
09
return
blueHist;
10
}
在這邊我們計算Blue通道的色彩分布,其中你會看到我們初始化DenseHistogram會需要輸入兩個參數,先看第二個BRange其實就是橫軸的起始數值到最大數值,而0-255剛好就是顏色的像素值範圍,所以我們要統計Blue通道的像素值分布狀況
再來是第一個參數,Bbin-是用來量化的數量,也就是我們可以把直方圖的區間切割出來,這邊設定8,換句話說就是約0-32,33-64,64-96等等這樣切出8個區間,最後只要是像素值在0-32中間的就會落到這個區塊,或像是像素值68會落在64-96這個區間,這樣的目的就是看你的色彩分布要記錄的多細緻,如果我只想要知道大概區塊的色彩,Bbin就可以切小一點
而這行則是透過index拿出Blue通道的影像(EmguCV通常使用的順序是Bgr所以index = 0 表示Blue)
1
blueHist.Calculate(
new
IImage[] { loadImg.Split()[0] },
false
,
null
);
最後使用內建直方圖繪製工具,就會出現如下的圖片
直方圖的多通道計算或不同色彩空間
1.多通道
除了計算單的通道外,也可同時計算多通道直方圖
如下是我們計算Blue與Green的程式
01
private
DenseHistogram CalHistBlueGreenHist() {
02
//計算Blue-Green單通道
03
int
[] BGbins = { 16, 16 };
//切割量化的數量
04
RangeF[] BGRanges =
new
RangeF[] {
new
RangeF(0, 255),
new
RangeF(0, 255) };
05
DenseHistogram bgHist =
new
DenseHistogram(BGbins, BGRanges);
06
//填入Blue-Green通道的顏色圖像
07
bgHist.Calculate(
new
IImage[] { loadImg.Split()[0], loadImg.Split()[1] },
false
,
null
);
08
09
return
bgHist;
10
}
因為多了一個Green通道,所以也要去多考慮Green通道的Bin與Range
然後在
1
bgHist.Calculate(
new
IImage[] { loadImg.Split()[0], loadImg.Split()[1] },
false
,
null
);
我們也要多切割出Green的通道影像資料來計算
2.不同色彩空間計算-HSV色彩空間
HSV色彩空間和RGB的空間分布顏色圖如下
RGB色彩空間: HSV色彩空間:
其中你會看到RGB的色彩分布是混再一起的,單個通道不畫足夠表現出完整的色彩
而HSV(Hue – Saturation - Value)則是把顏色與飽和度還有明暗度分離,所以Hue除了無法表達黑->灰->白以外,其餘的各大色彩足夠表示
借用Wiki的解說
Hue:色相(H)是色彩的基本屬性,就是平常所說的顏色名稱,如紅色、黃色等。(顏色也就是可見光:紅橙黃綠青藍紫)
Saturation :飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取0-100%的數值。
Value:明度(V),亮度(L),取0-100%。
所以通常如果你的色彩辨識不希望考慮到明暗度的話,就可以使用HSV空間,並只去辨識一張影像中Hue的色彩分布相似度
以下是HSV色彩空間中的Hue直方圖計算
01
private
DenseHistogram CalHistHueHist()
02
{
03
//計算Hsv的H-S
04
int
[] Huebins = { 8};
//切割量化的數量{HBin,SBin}
05
RangeF[] HueRanges =
new
RangeF[] {
new
RangeF(0, 180) };
//H
06
DenseHistogram hsHist =
new
DenseHistogram(Huebins, HueRanges);
07
//填入H-S通道的顏色圖像
08
hsHist.Calculate(
new
IImage[] { loadImg.Convert< Hsv,
byte
>().Split()[0] },
false
,
null
);
09
10
}
這邊會看到一個有趣的事情是,色相Hue明明是在0~360度,為何會給他180呢?
因為當我們把色彩空間做轉換後,放到的資料結構預設是8bit,而為了符合在這個大小下,會把Hue/2 => 180度的Range
而飽和度Saturation 與明度Value原本的百分比是以(0-1)表示法也會變成0-255
如下是OpenCV中的CvtColor解釋(EmguCV是從新包裝OpenCV,所以核心要看OpenCV):
另外,以下此行是先轉換到HSV的色彩空間在做計算
1
hsHist.Calculate(
new
IImage[] { loadImg.Convert< Hsv,
byte
>().Split()[0] },
false
,
null
);
然後如下圖會看到色彩分布的圖形不一樣
用有自己繪製的直方圖來看一下會是這樣(和上面的Hue分布很像):
HSV色彩空間中的HS直方圖計算:
01
private
DenseHistogram CalHistHSHist() {
02
//計算Hsv的H-S
03
int
[] HSbins = { 8, 16 };
//切割量化的數量{HBin,SBin}
04
RangeF[] HSRanges =
new
RangeF[] {
new
RangeF(0, 180),
new
RangeF(0, 255) };
//H,S
05
DenseHistogram hsHist =
new
DenseHistogram(HSbins, HSRanges);
06
//填入H-S通道的顏色圖像
07
hsHist.Calculate(
new
IImage[] { loadImg.Convert< Hsv,
byte
>().Split()[0], loadImg.Convert< Hsv,
byte
>().Split()[1] },
false
,
null
);
08
09
return
hsHist;
10
}
不過....使用DenseHistogram的資料結構如果是多通道的話,無法在HistogramViewer與HistogramBox顯示(試過行不通),所以這邊我用自己會的結果來看
這邊會看到主要色彩分成八大塊,然後每一塊的顏色會有亮度條(共16條)即是飽和度的Bin數量
HelloHistogramForm_calHistogramByDenseHistogram.zip
結論
希望透過這篇文章讓想要使用、計算直方圖的朋友可以更加瞭解,也希望以後可以不要忘了直方圖這基本的影像應用
下一篇會介紹如何使用CvInvoke(直接調用openCV的函式)來計算直方圖
PS:以上文章圖片如果沒有包含本部落格的簽名,皆是取自網路
- [EmguCV|C#]使用EmguCV的DenseHistogram類別計算與紀錄圖像直方圖-直方圖(Histogram)系列(2)
- [EmguCV|C#]使用CvInvoke自己繪製色彩直方圖-直方圖(Hitsogram)系列(4)
- EmguCV的配置与使用
- OpenCV+C#]开发环境的搭建EmguCV
- EmguCV+VS2010 C#,cvinvoke异常的解决办法
- 【C#】基于Opencv/Emgucv的身份证识别
- C#+Emgucv视频获取
- EmguCV之ImageBox和HistogramBox的使用
- 有关EmguCV使用技巧的简单汇总
- emgucv使用遇到的一些问题
- Emgucv摄像头使用
- VS2010平台下的OpenCV、EmguCV( C#)安装、使用配置
- c#+EmguCv 图像灰度化
- 【EmguCV】EmguCV各种调用
- 在Unity3D中使用EmguCV
- 示例:使用EmguCV视频截图
- 使用EmguCv播放指定视频
- 使用EmguCV处理Kinect数据流
- 中国汽车品牌口碑榜之:--2013年第3季度福州商用车综合口碑排名
- 嵌入式基础:ARM下GCC交叉编译器的制作
- mac 使用
- linux之tmpfs
- 自定义标签,时间戳与日期时间转换 jsp页面
- [EmguCV|C#]使用EmguCV的DenseHistogram類別計算與紀錄圖像直方圖-直方圖(Histogram)系列(2)
- 内核调试相关变量说明
- 汇编中.word的具体用途是什么?
- 新的开始
- c++中关于字符重载
- 清华学校网站
- 卷积与相关
- Js判断客户端是否为PC还是手持移动设备
- log4j