Programming 2
Counting Pixels with Histograms
1.histogram:
(1) Computing the image histogram. (2) Equalize the image. (3) Applying Look-up Tables to Modify Image Appearance.
此程式碼使用影像尺寸320*240。
讀取影像成灰階影像,存檔並顯示。
輸出結果。
2.使用 getHistogram 函式將影像的直方圖內容儲存在 histo 中並輸出文字,接著使用 getHistogramImage 函式產生直方圖。
輸出結果中Value為像素強度,後者數值為此強度出現次數。
直方圖
3.在直方圖上畫一條垂直線,該線位於像素值為70的位置,目的是為了在視覺化直方圖時,更容易地看到直方圖中的峰值位置。line 函式中,第一個參數 hi 是直方圖所在的影像 image,第二個和第三個參數則是線的起點和終點,最後一個參數則是指定線的顏色,128即灰色。
輸出畫線的直方圖
4.接著將影像二值化,將影像中大於70的像素值設為255,小於或等於70的像素值設為0,產生一個二值化的影像 thresholded,並顯示。接著再將 thresholded 反相顯示,即將255的像素值變成0,0變成255,屬於反白的概念,並將其存為一個名為 "binary" 的 bmp 影像。
threshold value=70。
原本 threshold value=70 的輸出,像素70以下都被轉為黑色,可見原本路面的位置大部分都大於70而被轉為255了。
接著 threshold value=100以及 threshold value=128,可見輸出黑色部分越來越多,在threshold value=128時的0比255多,代表原始影像的像素分布在128以下的像素多於128以上的像素。
threshold value=100。
threshold value=128。
5.使用 equalize 函式對影像進行直方圖均衡化,將結果存放於 eq 中。
生成新的直方圖。
直方圖均衡化是一種影像處理技術,用來增強影像的對比度和亮度分布,可以將一張影像的像素值分布變得更加平坦,使得亮度更加均勻,提高影像的視覺品質和識別效果。
Equalized 後輸出。
Equalized 後的直方圖。
6.使用 stretch 函式,將影像進行對比度拉伸,並將結果存在 str。
生成新的直方圖。
stretch函式中,參數 0.01f 是控制拉伸比例的係數,影像中強度最低的 1% 像素值以及最高的 1% 像素值會被映射到 0 和 255 ,其餘像素的值則按比例拉伸,以提高對比度。
stretch 後輸出。
stretch 後的直方圖。
接著我做了係數0.02f的stretch但結果不明顯,故直接提升到0.05f,可見最高最低5%的像素被映射過後,影像整體的對比度提高了一些。
透過直方圖可以觀察到0和255的出現次數非常高。
stretch(image,0.05f)
stretch(image,0.05f)直方圖
7.建立一個 Look-up Table,實現反轉影像的效果,並使用 applyLookUp 顯示。
LUT 是一個用來對影像進行顏色映射的表格,可以將影像中某些顏色的像素值對應到其他顏色的像素值,從而達到顏色調整的目的。將LUT 設為一個 1x256 的矩陣,其中每個元素的值是一個 8-bit 的無號整數(CV_8U),代表將原本的像素值 i 映射到新的像素值 255-i,即將原本的亮度值做反轉的處理。
反轉後的輸出
結果分析:
getHistogram:可用來了解影像中像素值的分布狀況,並從中分析出一些資訊,例如影像的對比度、明暗程度等。
thresholded:可將影像二值化,將灰階影像轉換成只有黑白兩種值的影像,方便後續進行圖像分割等處理。
equalize:可對影像進行直方圖均衡化處理,增強影像的對比度,使影像中的細節更加明顯。
stretch:可對影像的像素值範圍進行調整,使影像中最暗和最亮的部分能更好地顯示出來,從而增強影像的對比度和細節。
遇到的問題:
編譯程式時發現疑似缺少histogram.h檔案,導致無法識別Histogram 1D。
解決方法:
查看課程材料中的README.txt了解在這次program中對應的程式碼需要的檔案以及影像,並將其分別加入至每個專案中解決此問題。
2.原本使用此圖輸出的直方圖黑色部分處於很小面積,檢查影像尺寸、格式有沒有出錯並想找出造成此結果的原因。
尺寸480*270
直方圖
解決方法:
由於原本使用的影像整體偏暗,觀察到直方圖數據顯示有大量的數據集中於其中幾個低強度的bin內而導致不好觀察,在我換了另一張分布範圍比較沒這麼集中的影像時,解決了這個問題,我認為這樣對此主題比較有觀察意義。
2.contentfinder.cpp:Backprojecting a Histogram to Detect Specific Image Content.
green-blue.jpg
green-blue3.jpg
此程式碼使用影像尺寸均為288*194。
1.將 green-blue 讀入為灰階影像,接著定義了一個ROI範圍,也就是目標區域並顯示。
2.使用 Histogram1D 物件 h 的 getHistogram() 方法計算 ROI 區域的灰階直方圖,並使用 getHistogramImage() 方法將直方圖轉換成圖像並顯示。
ROI的直方圖。
3.使用 ContentFinder 物件,設定了直方圖、閥值、反向投影及轉換等參數。
finder.setHistogram(hist):設定要使用的直方圖 hist。
finder.setThreshold(-1.0f):將閥值設為 -1,表示所有像素都會被考慮進入反向投影的計算,而不會進行閥值過濾。
finder.find(image):將 image 進行反向投影,並將結果儲存在 result1 中。
result1.convertTo(tmp,CV_8U,-1.0,255.0):將反向投影結果 result1 轉換為 8 位元無號整數型別的影像,並將值域從 [-1, 1] 轉換為 [0, 255]。
cv::imshow("Backprojection result",tmp):顯示反向投影的結果影像。
反向投影的結果。
反向投影會將待測影像中所有像素的像素值映射到一個新的影像中,這個新的影像中每個像素的值代表了該像素的顏色在訓練影像中目標物體的顏色分佈中的相對出現頻率。通過比較反向投影影像和訓練影像中的目標物體的顏色分佈,可以找出待測影像中可能包含目標物體的區域。這樣就可以實現物件偵測和影像分割的目的。
4.將閥值設定為 0.12f再次進行反向投影。
5.接著,使用 rectangle 在圖像上繪製一個矩形,該矩形是定義 ROI 的矩形。
"Image" 顯示繪製後的原始圖像,"Detection Result" 顯示反向投影圖像。
0.12f代表在反向投影後,將所有值低於 0.12f 的像素都設為 0,高於等於 0.12f 的像素都設為 255。
rectangle 中,image為要繪製矩形的影像,Rect 為要繪製的矩形範圍,由左上角的座標和長寬表示,Scalar 為矩形的顏色,是用黑色 (0,0,0) 表示。
ROI的影像範圍。
閥值 0.12f 的反像投影結果。
6.利用直方圖在彩色圖像中檢測特定的顏色。
讀取彩色圖像 green-blue.jpg 並將 ROI 改為 (0, 0, 100, 45),雲的區域。
使用ColorHistogram產生彩色 ROI 的直方圖,hc.setSize(8) 指定直方圖中的bin數量為8,色調的範圍被分成了8個區間。
使用 hc.getHistogram(imageROI) 產生取得 ROI 的直方圖。
設定反向投影使用的直方圖及閥值並產生反向投影圖像。
Color Detection Result。
7.讀取並顯示第二張彩色影像 green-blue3.jpg ,並且沿用相同的直方圖和閥值設定,對這張影像進行反向投影。
第二章影像。
反向投影結果。
8.設定直方圖的 bin 數量為 256,並且計算 ROI 區域的 ab 色彩空間的直方圖。計算出直方圖後,將它轉換成 8 位元,並將像素值縮放到 0 到 255 的範圍並顯示。接著設置直方圖及閥值。
LAB色彩空間是一種與RGB色彩空間和CMYK色彩空間不同的色彩空間模型,包含了三個通道:L通道表示亮度,a通道表示從綠色到紅色的值,b通道表示從藍色到黃色的值。
ROI 的 ab 色彩空間直方圖。
9.將兩張影像 green-blue 以及 green-blue3 轉換為 Lab 色彩空間的格式,宣告一個整數陣列 ch,包含 1 和 2,代表只取 Lab 色彩空間中的 a 和 b 兩個通道的值。接著使用剛剛從 ROI 產生的 ab 直方圖分別對兩張影像反向投影並顯示。
Lab 色彩空間中的 a 和 b 通道的值域是 [-128, 127],而直方圖的 bin 數量是 256,因此需要將像素值的範圍設定為 [0, 256]。
green-blue 的反像投影。
green-blue3 的反像投影。
10.在 green-blue 影像上畫出 ROI 的範圍並顯示,接著將 bin 設為 180 階並生成先前設定雲域 ROI 的 Hue 直方圖 colorhist。
Hue是一個顏色的屬性,描述的是顏色的純度或色調。在色彩模型中,Hue是一個色彩環,其中包含了所有可能的顏色,從紅色開始,一直到紫色,可以用一個度數來表示,從0°開始,一直到360°。
在OpenCV中,Hue的值範圍通常是0到180,因為在它被儲存在一個8位元的數值中,範圍是0到255。然而,Hue的真實範圍是0到360,因此需要進行一些轉換才能在OpenCV中使用。
green-blue3 的 ROI 範圍。
Hue色彩環。
11.使用Hue通道進行直方圖反向投影 green-blue 以及 green-blue3 並顯示。
將兩張影像轉換為 HSV 色彩空間的格式,並將整數陣列 ch 設為 0,代表只取 HSV 色彩空間中的 Hue 通道的值。
HSV是一種常用於圖像處理和計算機視覺的色彩模型,將色彩信息分成三個維度,分別是色相(Hue),取值範圍為0-360度,對應著不同的顏色 ; 飽和度(Saturation),取值範圍為0-1,代表色彩的純度和灰度的深淺程度 ; 亮度(Value),取值範圍為0-1,代表色彩的明亮程度。
HSV模型更貼近人類對顏色的認知,方便用於色彩識別、顏色區分等應用。
green-blue 的反向投影結果。
green-blue3 的反向投影結果。
結果分析:
灰階影像在使用閥值為-1f 的反向投影 Backprojection result 中,因為所有像素都被考慮進入反向投影的計算,而沒有進行閥值過濾,這樣的結果幾乎與尋找的目的完全相反,除了設定為天空範圍的 ROI 之外的像素幾乎都被設為 255 了,所以必須使用適當的閥值進行過濾,才能得到想要的結果。例如在 Detection Result 之前將閥值設為0.12f,閾值的範圍都是0到1之間的浮點數,代表影像像素的亮度值在閾值以上就會被標記為前景物件,反之則是背景物件,結果也找到天空大概的範圍,雖然不是特別準確。
彩色影像的反向投影結果 Color Detection Result 中觀察到,雖然所選的雲域 ROI 包含了一些藍色天空,但準確性高了相當多。
在Lab色彩空間格式的反向投影 Result ab (1) 表現得相當準確,但投影到與 ROI 不同的影像 green-blue 時, Result ab (2) 的準確率卻有所下降,我認為是兩張影像原本的顏色就有所不同,雲的像素有所差異造成的。
在HSV色彩空間中,Hue通道代表了色相信息,而S和V通道代表了飽和度和亮度信息。如果你只關注影像中物體的色相特徵,使用HUE通道進行反向投影可以更有效地提取目標物體的位置信息,因為在HUE通道中物體的色相信息更加突出,相對地對飽和度和亮度信息的依賴較小。而在使用彩色影像進行反向投影時,會考慮到所有通道的信息,因此可能會對飽和度和亮度信息產生較大的影響,從而導致目標物體的位置提取效果不如使用HUE通道的方法。但我觀察到 Result Hue (1) 和 Result Hue (2) 的結果並沒有比直接使用彩色影像進行反投影的好,有可能是我所選的 ROI 對於飽和度和亮度信息的依賴較大造成的。
3.finder.cpp: Using the Mean-shift Algorithm to Find an Object.
1.讀取彩色影像 GEM.jpg ,設定矩形並繪製,並將其設為 ROI 。
設定一個矩形區域 rect,其左上角座標為 (110, 25),寬度為65,高度為100。
使用rectangle 函數在原圖像上畫出此矩形,顏色為紅色。
從原圖像image中剪切出矩形區域,即 ROI,使用OpenCV的Mat操作符,並將其存儲在imageROI中,後續的操作都是針對此矩形區域進行的。
原圖尺寸為400*400。
2.設定搜尋範圍及閥值。
定義了一個最低飽和度閥值 minSat,代表在 HSV 色彩空間中飽和度低於此閥值的像素會被忽略,因為這些像素不夠鮮豔,不太可能是要搜尋的物件的一部分。
使用 getHueHistogram 方法來計算 GEM 臉部 ROI 區域中色調(hue)的直方圖。
使用setHistogram 方法將 GEM 臉部 ROI 區域中,色調的直方圖設定為要搜尋的對象的特徵,以便在後續搜尋時使用。
使用 setThreshold 方法將閥值設定為 0.2f,這代表在後續搜尋時,只有像素與 ROI 區域中的色調直方圖的相似度高於 0.2f 的像素才會被視為可能是要搜尋的物件的一部分。
3.對輸入的彩色圖像做一些前處理,以便在後面使用顏色直方圖對其進行目標檢測和跟蹤。
將輸入圖像 image 轉換為 HSV 色彩空間的形式,以便對其進行色相、飽和度和亮度的分離。
通過 split 函數分離 HSV 色彩空間中的每個通道,得到三個單通道的圖像 v[0]、v[1] 和 v[2],分別代表色相、飽和度和亮度。
對飽和度通道進行處理,將其二值化,將低於最低飽和閾值的像素值設為0,高於最低飽和閾值的像素值設為255,生成一個遮罩圖像。
minSat=65。
白色為飽和度閥值以上區域。
4.讀取並顯示第二張彩色影像 GEM2.jpg 後將其轉換為 HSV 色彩空間的形式。
5.使用 ContentFinder 對 hsv 圖像進行直方圖反向投影,不使用閾值進行二值化,並顯示。
定義一個整數陣列 ch,值為 0,表示只使用 H 通道的直方圖進行反向投影。
將 ContentFinder 的閾值設置為-1.0f,表示不進行閾值處理。
對 hsv 圖像進行直方圖反向投影,0.0f 為H通道的最小值,180.0f 為最大值,第四個參數是用於指定使用哪些通道進行反向投影。這裡只使用了H通道,因此傳入的是 ch。
反向投影結果。
6.使用 Mean-Shift 演算法完成目標跟蹤後,將跟蹤的結果視覺化出來。
將原本 ROI 設定的矩形範圍在原始影像上畫出,並設定顏色為紅色。
建立一個 cv::TermCriteria 物件 criteria,這個物件會在 Mean-Shift 演算法中用來控制演算的停止條件。其中使用了 MAX_ITER 和 EPS 這兩個常數,分別表示最大迭代次數和最小移動距離。
執行 Mean-Shift 演算法,其中第一個引數 result 是上一個步驟中計算出的反向投影結果,第二個引數 rect 是設定的初始矩形範圍,第三個引數 criteria 是上述設定的停止條件。這個函數會返回一個整數值,表示演算法是否成功,如果成功則返回迭代次數。
在原始影像上畫出跟蹤結果的矩形範圍,並使用 (0,255,0) 設定為綠色,以區別之前畫的紅色矩形。
Mean-Shift 結果。
Mean-Shift:
Mean-Shift 演算法會計算當前窗口的重心,並以此不斷更新窗口的位置。
重心計算方式為對窗口中的所有像素進行權重平均,權重是像素值的概率分布,即目標直方圖中每個bin的值除以窗口中所有像素數量。
計算完成移動窗口,直到窗口位置不再改變或達到最大迭代次數,或者認為目標已經被跟蹤成功。如果窗口位置不再改變,則認為目標已經穩定,跟蹤成功;否則則視為跟蹤失敗。
輸出顯示了迭代次數為8次,表示計算以及移動窗口重複了八次達成終止條件。
結果分析:
關於 ROI 的範圍,最初選擇不夠大導致 Mean-Shift 結果不理想,它的計算方式為對窗口中的所有像素進行權重平均,所以當我加大範圍時開始變得相對準確,涵蓋到部分頭髮及完整面部輪廓。
遇到的問題:
關於影像的選擇,雖然是同一個人物,但臉部光線色澤有所不同,造成沒辦法追蹤的現象。
解決方法:
以尋找同一環境條件下用相同攝影設備拍攝出的不同影像為主。
尋找到相似光線顏色的影像之後,發現尺寸和解析度不同,調整成一樣大小後變成臉部的大小不一樣,無法做跟蹤。
解決方法:
由於原本解析度就不同,又必須確保調整後臉部的大小一致,只能在縮放與剪裁當中分成多次步驟完成。
4.retrieve.cpp: Retrieving Similar Images using Histogram Comparison
此程式碼使用以下九張影像進行實驗,尺寸均為276*184。
出處:昵圖網。
reference
1
2
3
4
5
6
7
8
1.讀取彩色影像 reference.jpg 作為參考影像並顯示。
2.分別讀入 1~8 影像,進行與參考圖像的比較,輸出相似度分數。
reference
輸出結果。
打開預先加入的 imageComparator.h 找到 compare 函式,這個函式的返回值是 double 型別,代表直方圖相似度的評分,該函數使用了 compareHist 函數進行直方圖比較。
其中 HISTCMP_INTERSECT 使用了交集方法,該方法簡單地比較每個 bin 中每個直方圖中的兩個值並保留最小值,相似性度量就是這些最小值的總和。 因此,具有沒有共同顏色的直方圖的兩個圖像將獲得交集值的 0,而兩個相同的直方圖將得到一個等於像素總數的值。
結果分析:
由於結果數值就是直方圖比較後保留最小值的總和,所以 276*184 的影像會造成此結果最大值為 50784,可以觀察到我所選擇的參考影像主要以天空及湖水加上少量綠色植物區域, 1~5 類似於參考影像,而7、8、9 則挑選顏色差異較大的影像,從輸出結果驗證了後三張的比較結果相對較低,而最高相似度的影像 2 確實與參考影像非常接近。
reference
2
5.integral.cpp: Create a binary image by adaptively setting a threshold
1.將原圖讀取為灰階影像並顯示。
宣告 binaryFixed 和 binaryAdaptive 物件,用來存儲閾值化後的影像資料。
2.進行二值化處理,閥值 70 最大值 255,結果存在 binaryFixed 並顯示。
原圖 259*194。
灰階影像。
3.使用 adaptiveThreshold 函數來進行自適應閾值處理,將灰階圖像轉換成二值化圖像,結果存在binaryAdaptive 並顯示。
blockSize 代表使用的方塊大小,threshold 代表閾值。
ADAPTIVE_THRESH_MEAN_C 為閾值處理方法,即使用方塊內像素的平均值作為閾值,將像素值小於閾值的設置為 0,大於等於閾值的設置為 255。
計算並輸出閾值處理所需的時間,單位為毫秒。
binaryFixed。
binaryAdaptive。
4.兩種方式計算積分影像。
使用 IntegralImage 類別,int 表示積分影像的數值型別,而 1 則表示圖像的通道數,使用 integral 函式計算位於 (35,65) 且寬 40、高 40 的區域的像素總和並輸出。
創建一個大小為 40x40、位置為 (35,65) 的 ROI 區域,並使用 sum 函式計算這個 ROI 的所有像素值總和並輸出。
輸出的總和數值。
5.使用 Mat 的 clone 函式,複製了一個 image 的副本,存到 binary 中,數據完全相同但內存地址是不同的,代表修改 binary 的數據時不會影響到 image 的數據。
nl 和 nc 分別是影像的行數和列數。
6.使用 integral 函數計算輸入影像 image 的積分影像,輸出結果是一個和輸入影像同樣大小的 iimage 形式的矩陣。CV_32S 是輸出矩陣的數據類型,表示輸出矩陣的元素是 32 位有號整數。
7.這兩個迴圈是在進行自適應區塊二值化,透過計算每個像素周圍一定區域內的平均值來決定閥值,將該像素二值化為黑或白。
假設區域左上角為 (x1, y1),右下角為 (x2, y2),則該區域的灰度值總和可以透過下式計算:sum = iimage(y2, x2) - iimage(y1, x2) - iimage(y2, x1) + iimage(y1, x1)
閥值為區域平均值 sum 減去先前設定的固定值 10。
data:指向 binary 中第 j 列第 i 個像素的指標,通過指標操作修改像素值。
idata1、idata2:指向積分影像 iimage 中第 j-halfSize 和 j+halfSize+1 列第 i-halfSize 和 i+halfSize+1 個元素的指標,通過指標操作計算區域總和。
sum:區域內所有像素的平均灰度值。
threshold:二值化閥值。
8.將影像邊緣處理為白色,使得邊緣區域不受影像處理算法的影響,避免因邊緣像素的不確定性對算法產生干擾。
將影像上下兩端的 halfSize 行像素值都設為 255 (白色)。
接著從 halfSize+1 行開始,到 nl - halfSize - 1 行結束,針對每一行的前 halfSize 像素和後 halfSize 像素,將其像素值都設為 255,將左右邊緣也設成白色。
9.輸出計時結果以及自適應區塊閾值處理結果。
Adaptive Threshold (integral)
10.使用 boxFilter 函數對 image 變量進行了模糊處理,產生一個經過平均濾波器的影像,並存儲在filtered變量中。
函數的第二個參數CV_8U表示輸出影像的深度為8位無符號整數,blockSize表示濾波器的尺寸。
11.使用image >= (filtered-threshold)將 image 變量二值化,生成一個二值影像並存在 binaryFiltered 中並輸出。
Adaptive Threshold (filtered)
結果分析:
在進行自適應閾值處理時,使用積分圖像和濾波器是兩種常見的方法。這些方法的主要區別在於如何計算圖像的局部平均值。
Adaptive Threshold (integral):積分圖像方法是通過預先計算圖像的積分圖,來計算每個像素周圍像素的平均值。這個方法只需要計算一次積分圖像,然後對於不同的窗口大小和閾值,可以快速地計算每個像素的閾值,因此速度較快。
Adaptive Threshold (filtered):濾波器方法需要在每個像素周圍計算一個窗口內的像素平均值。這需要在每個像素上進行一次卷積或濾波操作,因此速度比積分圖方法慢。而且對於每個窗口大小和閾值,濾波器方法都需要進行一次完整的濾波操作,因此計算量也較大。
綜上所述,積分圖方法在計算速度上具有優勢,而濾波器方法則需要更多的計算量和時間。
6.tracking.cpp: Locate an object in the image
bike1。
bike2。
此程式碼的影像是由參考書的影檔另外擷取出來腳踏車在不同位置的影像(不同於程式碼使用的兩張影像)。
1.讀取第一張影像為灰階影像 image ,並且通過多次測試找到 ROI 的區域為 (193,120),寬度25高度30的矩形,並且計算此矩形像素總和並輸出sum。
2.將影像使用 integral 函式處理成積分影像,並且從此積分影像找出 ROI 區域並輸出。
ROI 矩形四個點,右下的典包含所有像素總和,減去右上及左下面積,再將左上點被重複扣掉的部分加回來,就是 ROI 區域的總和。
第一種方法是通過 sum 函數計算 ROI 區域的像素值總和,這種方法會遍歷ROI區域的每一個像素並進行加總。
第二種方法是通過計算積分影像的方式來計算 ROI 區域的像素總和,這種方法通過事先計算出積分影像,可以快速計算出 ROI 區域的像素總和,而不需要遍歷 ROI 區域的每一個像素。在計算多個ROI區域的像素總和時,使用積分影像的方法可以顯著提高計算速度。
3.使用 getHistogram 產生 ROI 的直方圖,並將bin設定為16個階段。
4.將影像轉換為二進位平面影像,然後使用積分影像計算指定區域的直方圖,再將直方圖轉換為圖像及顯示。
convertToBinaryPlanes 函數是將灰度影像轉換為二進位平面影像,其中的 planes 是二進位平面影像的容器。
IntegralImage<float,16>:創建一個積分影像,可以計算每個像素值出現的次數。
intHisto(xo,yo,width,height):使用積分影像計算指定區域的直方圖。
h.getImageOfHistogram:函數將直方圖轉換為圖像以便顯示。16 是指直方圖的 bin 數量,這也要與 convertToBinaryPlanes 函數中的 bin 數量一致。
在數值上,這兩個直方圖應該是非常接近,但不一定完全相同。因為算法或浮點數精度等因素,在計算過程中可能有一些微小的差異,這些都可能導致最終的結果略有不同。
5.讀取第二章影像為灰階影像 secondImage,將其轉換為16平面二進制影像,並使用積分影像的方式計算直方圖數據 intHistogram,接著取出先前 ROI 位置的直方圖並顯示。
Current Histogram
直方圖有所改變,代表在這張影像的 ROI 區域像素不同。
6.使用 compareHist 函數來計算第一張影像和第二章影像直方圖之間的距離並輸出。
HISTCMP_INTERSECT是比較直方圖的方法,此處是使用交集比較法。
compareHist 函式會返回一個浮點數,值越大表示兩個直方圖之間越相似。
7.接著對設定的範圍逐一比對及輸出,最後將 maxSimilarity 內的最大相似度輸出。
......
第一次比對的值為432,接著 x 和 y 分別移動做一連串比對得到上面數值,最後得出對大相似度的最標及數值625。
8.最後我們將這些實驗步驟的所有輸出清楚的顯示出來觀察。
原影像之 ROI 區域。
第二章影像。
追蹤結果。
結果分析與問題:
在這個程式碼實驗中,初步學習到了使用直方圖操作物件追蹤在兩張影像上的實現,結果是成功的,不過兩張影像不同的地方非常少,好像才能達成這樣方式的物件追蹤,在找影像的時候就遇到滿大的問題,物件移動了位置但本身也產生變化,例如人體的動作及形狀、鳥類飛翔時翅膀開闔,都大幅改變了 ROI 的直方圖數據,接著是移動前後的角度變化也會導致 ROI 最後相差太大,所以最後我使用了參考書 image 內的影像檔案,擷取另外兩張影像來實驗。