本文所述的所謂條紋,並不是指雜色的條紋,而是觀感上把圖像割裂,讓圖像變模糊的條紋。這種模糊的條紋有可能在驅動類似ov2640這樣的攝像頭,或是MCU 8080接口的屏幕時出現。
我保存了一幀有這個現象的攝像頭採集回來的圖片,如下圖。可以看到,圖片中豎向的內容像是被切開了,變得異常模糊。實際上在這個距離上320*240的分辨率還是可以看清楚字的。
這種現象實際上是由於像素錯位產生的。假設一共有8個像素,顯示正常內容時,像素的排布方式應該如下所示
A0 | B0 | C0 | D0 |
A1 | B1 | C1 | D1 |
而產生這樣現象的時候你看到的像素排列實際上是這樣的:
B0 | A0 | D0 | C0 |
B1 | A1 | D1 | C1 |
即左右兩個像素點的位置反了,所以看到的圖像在觀感上產生了豎直方向的條紋。有種被撕裂的感覺。那們這樣的現象是如何產生的呢?
有些器件在對其通信方式進行配置的時候,可能選擇了“字傳送”的模式。即攝像頭一次性發送32位數據或者MCU發送32位的數據至屏幕上。對於RGB565格式的數據幀來說,半字的數據剛好是一個像素。如果用一個字母代表一個半字的話,在內存中,他們可能乖巧地按照ABCD的順序排列。可是當如果用一個字長度的指針訪問它的起始地址的話,讀出來一個字的內容就變成了BA,即原來第二個像素的數據變成了這個字的高16位。當發送方將這個字以MSB的形式發送的話。接收方按順序收到的第一個數據實際上就是第二個像素的內容而不是第一個像素了。這樣循環發送,整個畫面上前後兩個像素的內容就都發生了反轉。
出現了這種問題應該怎麼修復呢?
有兩種方法可以參考,一種是用軟件將相鄰兩個像素的數據進行調換,還有一種是更改數據發送方式的配置,讓發送方半字半字地按順序發送就可以了。
用軟件地方式可能更簡單一些,不需要深入研究數據傳送的配置。這邊附上一個將相鄰半字數據調換的代碼片段,方便大家快速驗證自己碰到的是不是這樣的問題。
//addr爲圖像數據的起始地址 resolution爲圖片像素
int exchang_pixel(uint16_t* addr,uint32_t resoltion)
{
if(NULL == addr)
return -1;
uint16_t data = 0;
for(int i = 0 ; i < resoltion ;i = i + 2)
{
data = addr[i];
addr[i] = addr[i + 1];
addr[i + 1] = data;
}
return 0;
}