項(xiàng)目簡介
1.1實(shí)驗(yàn)?zāi)繕?biāo)重述
ARM架構(gòu)的微處理器在追求低成本、低功耗和高性能的嵌入式系統(tǒng)領(lǐng)域占有主導(dǎo)地位,學(xué)習(xí)ARM微處理器的嵌入式系統(tǒng)設(shè)計(jì)對于未來的學(xué)習(xí)與實(shí)踐都有重要的意義。本次實(shí)驗(yàn),主要是基于KDLAB-I 嵌入式系統(tǒng)實(shí)驗(yàn)平臺(核心為ARM9架構(gòu)的S3C2440微處理器),在Linux系統(tǒng)下進(jìn)行設(shè)計(jì)與編程,利用OV9650攝像頭實(shí)現(xiàn)攝像、采集圖片、分析圖片、識別顏色的功能。
九層之臺,起于壘土,整個(gè)實(shí)驗(yàn)跨度達(dá)兩周,具體言之,又可以細(xì)分為以下幾個(gè)目標(biāo):
1、 熟悉Linux虛擬機(jī)的安裝和Linux系統(tǒng)的使用,掌握常見的命令,熟悉Linux系統(tǒng)下的操作邏輯;
2、 了解ARM嵌入式Linux系統(tǒng)的開發(fā)過程,掌握修改、編寫、燒 寫應(yīng)用程序和驅(qū)動(dòng)程序的方法;
3、 掌握嵌入式Linux系統(tǒng)開發(fā)交叉編譯環(huán)境的建立和使用;
4、 熟悉實(shí)驗(yàn)臺上常用外設(shè)的使用方法和連接方式;
5、 熟練掌握攝像頭的應(yīng)用程序的編寫和調(diào)試;
6、 熟悉RGB-565、RGB-888和HSI等常見顏色空間的轉(zhuǎn)換以及編程的實(shí)現(xiàn);
7、 掌握位圖的保存格式、數(shù)據(jù)格式和保存方法,并在Linux下編程實(shí)現(xiàn);
8、 掌握八鄰域生長算法的算法核心和編程實(shí)現(xiàn),并能夠在嵌入式 Linux系統(tǒng)中實(shí)現(xiàn)對拍攝圖片的正確連通;
9、 熟悉嵌入式系統(tǒng)的編程和調(diào)試方法,學(xué)會利用輸出來進(jìn)行調(diào)試;
1.2作品功能分析
1、 攝像頭能夠?qū)崿F(xiàn)實(shí)時(shí)監(jiān)視功能,將拍攝到的圖像實(shí)時(shí)顯示在 LCD屏幕上;
2、 具備截圖功能,能夠定時(shí)或根據(jù)輸入保存當(dāng)時(shí)的實(shí)時(shí)畫面并另存為圖片;
3、 具備分析功能,能夠判別圖中是否存在面積達(dá)到一定大小的紅色色塊,并判定其形心和半徑;
4、 具備結(jié)果可視化功能,可以將圖片處理為除原圖紅色區(qū)域外均為黑色的圖形,更加直觀;
二、功能流程圖
三、實(shí)驗(yàn)過程
準(zhǔn)備:Linux平臺下ARM嵌入式編程基本操作
主要包括基本文件操作、定制與修改內(nèi)核、給開發(fā)板燒寫定制的嵌入式Linux系統(tǒng)以及虛擬機(jī)與ARM9開發(fā)板的通訊。
其中,燒寫系統(tǒng)或許是最重要的一項(xiàng)技能了,因?yàn)樵趯?shí)驗(yàn)的過程中幾乎每天都會遇到莫名其妙的故障,甚至連重啟都解決不了(比如無限自動(dòng)重啟),這時(shí)候我就采取了最笨的辦法——重新安裝系統(tǒng)。
例程學(xué)習(xí)——camtest.cpp
Trect類
例程將TRect用作屏幕顯示的基類,定義了圖像存儲的起始地址Addr, 圖像的尺寸Size、寬度Width、高度 Height、每行圖像存儲時(shí)占 用的字節(jié)數(shù)LineLen以及圖像的位數(shù)BPP,并聲明和定義了將緩存數(shù)據(jù)顯示到屏幕上的DrawRect函數(shù)和清屏函數(shù)Clear。在這次實(shí)驗(yàn)中,完成bmp圖像的存儲和圖像分析功能的SavePic函數(shù)都是通過在DrawRect基礎(chǔ)上加以修改來實(shí)現(xiàn)的。
TFrameBuffer類
TFrameBuffer作為TRect類的派生類,主要作為緩存,將 TVideo存儲的圖片信息通過映射放到內(nèi)存中,便于以后的直接讀 寫,也可以少用read()和write()這類讀寫函數(shù),加快讀寫 速度,其他部分沒有太大的改動(dòng)。
TVideo類
TVideo同樣是TRect類的派生類,這個(gè)派生類主要負(fù)責(zé)將攝像頭拍攝到的圖像存儲在緩存區(qū)中,以待TFrameBuffer轉(zhuǎn)存和顯示。
主函數(shù)
Camtest的主函數(shù)比較簡單,短短的幾行卻完成了很多事情,定義了一個(gè)TFrameBuffer對象和一個(gè)TVideo對象,調(diào)用FetchPicture函數(shù)存儲圖像之后,再調(diào)用DrawRect將圖像顯示到屏幕上。使用for結(jié)構(gòu)無限循環(huán)此動(dòng)作,并在最外層使用try-catch的結(jié)構(gòu)來捕捉意外動(dòng)作。
雙線程
需求分析
最初并沒有打算使用雙線程,但是在仔細(xì)分析之后,如果需要加入按鍵來決定是否采集分析圖像,那么久不能使用單線程,否則將會出現(xiàn)用戶不按鍵,系統(tǒng)就一直等待的現(xiàn)象,這顯然不是一個(gè)合格的系統(tǒng)所應(yīng)有的樣子。所以還是硬著頭皮使用了雙線程。一個(gè)線程負(fù)責(zé)鍵盤的檢測,另一個(gè)線程負(fù)責(zé)實(shí)時(shí)拍攝和顯示功能,并且,沒有設(shè)置互斥量進(jìn)行交互以保證完全的實(shí)時(shí)運(yùn)行,設(shè)置了一個(gè)信息量以負(fù)責(zé)兩個(gè)線程之間的信息傳遞。
雙線程例程pthread學(xué)習(xí)
在雙線程的例程pthread中,首先聲明了互斥量pthread_tmutex,之后聲明了主線程writer_function和子線程reader_function,在主函數(shù)中創(chuàng)建了子線程的進(jìn)程,而主函數(shù)則運(yùn)行主線程,兩者通過互斥量進(jìn)行交互,分別作為生產(chǎn)者和消費(fèi)者增加和減少虛擬的緩存buffer_has_item,并在PC終端上對剩余的緩存產(chǎn)品進(jìn)行顯示。
雙線程設(shè)計(jì)
基于之前的分析,將雙線程例程中的互斥量去掉以保證兩個(gè)線程能夠完全獨(dú)立地工作。當(dāng)然在Makefile中還要在編譯語句的最后加上-lpthread,把多線程的庫鏈接上。在兩個(gè)獨(dú)立的線程中進(jìn)一步添加功能。
顏色識別
什么是顏色空間
顏色通常用三個(gè)相對獨(dú)立的屬性來描述,三個(gè)獨(dú)立變量綜合作用,自然就構(gòu)成一個(gè)空間坐標(biāo),這就是顏色空間。而顏色可以由不同的角度,用三個(gè)一組的不同屬性加以描述,就產(chǎn)生了不同的顏色空間。雖然被描述的對象顏色是客觀存在的,但是很明顯這是多指標(biāo)非線性的,由于不同場合的需求不同,因此不同的顏色空間仍有存在的必要。顏色空間按照基本結(jié)構(gòu)可以分兩大類:基色顏色空間和色、亮分離顏色空間。前者的典型是RGB;后者包括 YCC/YUV、Lab、以及一批“色相類顏色空間”。
RGB顏色空間
RGB顏色空間是一種大的分類,具體而言RGB空間還包含多種空間,其中sRGB是HP和Microsoft聯(lián)合制定的標(biāo)準(zhǔn)RGB空間,除此之外還有Adobe RGB,Apple RGB,ColorMatch RGB等等,他們通過不同的方式表示RGB三種顏色,使得它們具有不同的色彩寬度,GAMMA值也是不一樣的,但是在此處并不需要多加討論。
本實(shí)驗(yàn)平臺上攝像頭OV9650回傳的數(shù)據(jù)是RGB565格式的,相對RGB888格式(俗稱24位真彩色)犧牲了一定的信息量,由于在想HSI空間轉(zhuǎn)換的時(shí)候需要全部的RGB信息,因此還需要轉(zhuǎn)化到RGB888格式,這其中更還涉及到補(bǔ)償,會在后面敘述。
HSI顏色空間
HSI模型屬于第二類色亮分離的顏色空間,其建立基于兩個(gè)重要的事實(shí): 1°L分量與圖像的彩色信息無關(guān);2°H和S分量與人感受顏色的方式是緊密相聯(lián)的。這些特點(diǎn)使得HSI模型非常適合彩色特性檢測與分析。

HSI模型是美國色彩學(xué)家孟塞爾(H.A.Munseu)于1915年提出的,它反映了人的視覺系統(tǒng)感知彩色的方式,用色調(diào)(Hue)、色飽和度(Saturation或Chroma)和亮度 (Intensity或Brightness)來描述色彩其中,色調(diào)與光波的波長有關(guān),它表示人的感官對不同顏色的感受,如紅色、綠色、藍(lán)色等,它也可表示一定范圍的顏色,如暖色、冷色等。飽和度 表示顏色的純度,純光譜色是完全飽和的,加入白光會稀釋飽和度。飽和度越大,顏色看起來就會越鮮艷,反之亦然。亮度 對應(yīng)成像亮度和圖像灰度,是顏色的明亮程度。HSI色彩空間可以用一個(gè)圓錐空間模型來描述。雖然這種圓錐模型相當(dāng)復(fù)雜,但確能把色調(diào)、亮度和色飽和度的變化情形表現(xiàn)得很清楚。為了便于色彩處理和識別,人的視覺系統(tǒng)經(jīng)常采用HSI色彩空間, 它比RGB色彩空間更符合人的視覺特性。在圖像處理和計(jì)算機(jī)視覺中大量算法都可在HSI色彩空間中方便地使用,它們可以分開處理而且是相互獨(dú)立的。因此,在HSI色彩空間可以大大簡化圖像分析和處理的工作量。HSI色彩空間和RGB色彩空間只是同一物理量的不同表示法,因而它們之間存在著轉(zhuǎn)換關(guān)系。
RGB565->RGB888
將RGB565格式轉(zhuǎn)換為RGB888以進(jìn)行到HIS顏色空間的轉(zhuǎn)換的必要性之前已經(jīng)講過。我們知道RGB565格式分別保存了色彩的RGB分量的高5位、6位、5位,那么,亟需做的一件事情就是決定如何添加低位信息,最直接的想法是低位補(bǔ)零,但是實(shí)踐表明效果并不好,現(xiàn)在被廣泛采用是是一種稱為量化補(bǔ)償?shù)姆椒?,有三個(gè)步驟:
1. 將原數(shù)據(jù)填充至高位
2. 對于低位,用原始數(shù)據(jù)的低位進(jìn)行補(bǔ)償
3. 如果仍然有未填充的位,繼續(xù)使用原始數(shù)據(jù)的低位進(jìn)行循環(huán)補(bǔ)償
解釋一下循環(huán)補(bǔ)償?shù)母拍睿?br>
16bit RGB565 -> 24bit RGB888 的轉(zhuǎn)換
8bit RGB565 R4 R3 R2 R1 R0 - - - G2 G1 G0 B1 B0
24bit RGB888 R2 R1 R0 0 0 0 0 0 G2 G1 G0 0 0 0 0 0 B1 B0 0 0 0 0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 0 0 G2 G1 G0 G2 G1 G0 0 0 B1 B0 B1 B0 0 0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 B1 B0
RGB顏色空間到HSI顏色空間的轉(zhuǎn)換
** 紅色界定**
量化補(bǔ)償只是優(yōu)化顯示效果,并不能改變實(shí)際所觀測的結(jié)果,所以,在編程的時(shí)候直接考慮從原始的RGB565格式的數(shù)據(jù)著手。
由于G是高6位,B是高5位參照網(wǎng)上資料,當(dāng)G、B均小于10左右,R大于200,可以視為紅色,故此處僅考慮G末位為000001/000000;
B為00000;紅色為111**;
即只有這幾種可能:
11100000 11101000 11110000 11111000 32+64+128+8+16=224,232,240,248
00000000 00100000 0/32
一些小Trick
宏與三目運(yùn)算符嵌套
在進(jìn)行RGB到HSI的轉(zhuǎn)換的時(shí)候,有一個(gè)比較RGB三者大小的步驟,本來是寫的if語句嵌套,但是想想貌似有點(diǎn)累贅,于是便選擇了三目運(yùn)算符的嵌套并寫成了宏,效果還不錯(cuò),減少了二十多行的代碼量。
#define MAX(a,b,c) ((a>b)?((a>c)?a:c):((b>c)?b:c))
實(shí)驗(yàn)記錄
Segmentation Fault
在嘗試進(jìn)行更進(jìn)一步的圖像處理的時(shí)候,試圖將圖像數(shù)據(jù)寫入數(shù)組再進(jìn)行分析,但是出現(xiàn)了
=============
RESOURCE
今天在REVIEW代碼的時(shí)候,發(fā)現(xiàn)了這樣一個(gè)宏定義:
define COLOR_TO_MTK_COLOR_SIMUL(color) ((((color) >> 19) & 0x1f) << 11) \
|((((color) >> 10) & 0x3f) << 5) \
|(((color) >> 3) & 0x1f)
大家知道這個(gè)宏是用來干什么的嗎?
仔細(xì)分析后,原來就是實(shí)現(xiàn)了RGB888到RGB565的轉(zhuǎn)換,查閱相關(guān)資料后,發(fā)現(xiàn)網(wǎng)絡(luò)上有一篇牛人寫的東東,在此和大家分享。
講一下量化壓縮與量化補(bǔ)償吧
在進(jìn)行色彩格式轉(zhuǎn)換的時(shí)候,經(jīng)常會遇到色彩量化位數(shù)的改變,比如說從 24bit RGB888 到 16bit RGB565 的色彩轉(zhuǎn)換。所謂量化壓縮與量化補(bǔ)償都是我個(gè)人所提出的概念,現(xiàn)說明如下。
量化壓縮,舉例:
24bit RGB888 -> 16bit RGB565 的轉(zhuǎn)換
24ibt RGB888 R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1 B0
16bit RGB656 R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 G2 B7 B6 B5 B4 B3
量化位數(shù)從8bit到5bit或6bit,取原8bit的高位,量化上做了壓縮,卻損失了精度。
量化補(bǔ)償,舉例:
16bit RGB565 -> 24bit RGB888 的轉(zhuǎn)換
16bit RGB656 R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0
24ibt RGB888 R4 R3 R2 R1 R0 0 0 0 G5 G4 G3 G2 G1 G0 0 0 B4 B3 B2 B1 B0 0 0 0
24ibt RGB888 R4 R3 R2 R1 R0 R2 R1 R0 G5 G4 G3 G2 G1 G0 G1 G0 B4 B3 B2 B1 B0 B2 B1 B0
說明:第二行的 24bit RGB888 數(shù)據(jù)為轉(zhuǎn)換后,未進(jìn)行補(bǔ)償?shù)臄?shù)據(jù),在精度上會有損失
第三行的 24bit RGB888 數(shù)據(jù)為經(jīng)過量化補(bǔ)償?shù)臄?shù)據(jù),對低位做了量化補(bǔ)償
可以很容易的證明,這樣的補(bǔ)償方法是一種合理的線性補(bǔ)償。補(bǔ)償?shù)脑砗芎唵危蠹易屑?xì)想一下就明白了,因此不再詳細(xì)說明。
總結(jié)一下:
量化壓縮的方法:三個(gè)字取高位
量化補(bǔ)償?shù)姆椒ǎ?/p>
1. 將原數(shù)據(jù)填充至高位
2. 對于低位,用原始數(shù)據(jù)的低位進(jìn)行補(bǔ)償
3. 如果仍然有未填充的位,繼續(xù)使用原始數(shù)據(jù)的低位進(jìn)行循環(huán)補(bǔ)償
解釋一下循環(huán)補(bǔ)償?shù)母拍睿?/p>
8bit RGB332 -> 24bit RGB888 的轉(zhuǎn)換
8bit RGB332 R2 R1 R0 G2 G1 G0 B1 B0
24bit RGB888 R2 R1 R0 0 0 0 0 0 G2 G1 G0 0 0 0 0 0 B1 B0 0 0 0 0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 0 0 G2 G1 G0 G2 G1 G0 0 0 B1 B0 B1 B0 0 0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 0 0
24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 B1 B0
看了這個(gè),應(yīng)該明白則么回事了吧,其中B分量,進(jìn)行了四輪的補(bǔ)償,達(dá)到要求。
量化補(bǔ)償?shù)谋匾?,從直覺上講,我所提出的這種補(bǔ)償方法是正確的(因?yàn)槲也]有嚴(yán)格的去證明),進(jìn)行這樣的補(bǔ)償,在做色彩各式轉(zhuǎn)換的時(shí)候,能夠明顯的改善色彩效果,減少精度上的損失。
對256色調(diào)色板模式的認(rèn)識和應(yīng)用,順便講一下這個(gè),因?yàn)榱炕瘔嚎s和量化補(bǔ)償剛好可以應(yīng)用到調(diào)色板模式下。大家都知道,很早以前就有人提過出256色的標(biāo)準(zhǔn)調(diào)色板的概念(有的人又稱之為抖動(dòng)調(diào)色板或者萬能調(diào)色板),其實(shí)這樣的調(diào)色板并不神秘。256色中,一個(gè)像素點(diǎn)用8bit表示,那么如果采用 8bit RGB332 的格式,一切問題都可以想通,并且可以進(jìn)行很好的處理了。對于每個(gè) RGB332 的顏色,都可以使用量化補(bǔ)償?shù)淖龇?,將其轉(zhuǎn)換為 24bit RGB888 的顏色格式,然后將其設(shè)置為調(diào)色板即可。這樣,實(shí)質(zhì)上是將256色調(diào)色板模式,轉(zhuǎn)換為了 8bit RGB332 的像素格式。這樣的調(diào)色板方式,更加利于某些方面的處理,比如調(diào)色板匹配、Alpha混合等。由于采用了這樣的方法,一個(gè)像素點(diǎn)的顏色值,與其實(shí)際的RGB顏色值,可以很方便的通過量化補(bǔ)償?shù)姆椒ㄞD(zhuǎn)換出來,然后就可以對各個(gè)顏色分量進(jìn)行計(jì)算,計(jì)算完畢,再使用量化壓縮的方法,就可以生成最終需要的顏色值。而所謂的調(diào)色板匹配的問題,當(dāng)然也更加好解決了。關(guān)鍵是要把問題想通,把握事物的本質(zhì),才能找到簡單而優(yōu)美的解決問題的方法。
以前我對標(biāo)準(zhǔn)調(diào)色板的認(rèn)識也存在很多錯(cuò)誤,導(dǎo)致在分析和解決問題上,沒有能找到最好的方法。網(wǎng)上也有許多人寫過有關(guān)256色模式下 Alpha Blending 的文章,但是都存在許多認(rèn)識上的不足,導(dǎo)致最后給出的算法時(shí)間和空間的復(fù)雜度都太大。我也有過一篇有關(guān)256色Alpha混合的文章,但限于當(dāng)時(shí)對事物的認(rèn)知能力,因此現(xiàn)在看來以前的許多文章是慘不忍睹。大家都在進(jìn)步,以后有機(jī)會再將新的認(rèn)識寫成文章,同大家分享。
