STM32開源光流定點 四軸 PIX

STM32開源光流定點 四軸 PIX

廢話不多說先上圖:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

硬體配置:
STM32F407VET6
MPU6050
VL53L0X

光流的概念是Gibson在1950年首先提出來的。它是空間運動物體在觀察成像平面上的畫素運動的瞬時速度,是利用影象序列中畫素在時間域上的變化以及相鄰幀之間的相關性來找到上一幀跟當前幀之間存在的對應關係,從而計算出相鄰幀之間物體的運動資訊的一種方法。一般而言,光流是由於場景中前景目標本身的移動、相機的運動,或者兩者的共同運動所產生的。其計算方法可以分為三類:
(1)基於區域或者基於特徵的匹配方法;(L-K的方法)
(2)基於頻域的方法;
(3)基於梯度的方法;
簡單來說,光流是空間運動物體在觀測成像平面上的畫素運動的“瞬時速度”。光流的研究是利用影象序列中的畫素強度資料的時域變化和相關性來確定各自畫素位置的“運動”。研究光流場的目的就是為了從圖片序列中近似得到不能直接得到的運動場。
光流法的前提假設:
(1)相鄰幀之間的亮度恆定;
(2)相鄰視訊幀的取幀時間連續,或者,相鄰幀之間物體的運動比較“微小”;
(3)保持空間一致性;即,同一子影象的畫素點具有相同的運動。

這裡寫圖片描述
一樣的手工焊接,焊的醜,就別在意那個了,功能實現最重要。
之前一直是用的PIXFLOW和匿名的光流 所以一直想自己做一個理解一下其中的過程
匿名的只是為了賺錢 所以不開源 只有看pixflow的原始碼了
其中擷取了一部分複製到了自己的工程裡

///////////////////////////////////////////////////////
//函式功能:檢測某點是否是特徵點
///////////////////////////////////////////////////////
static inline uint32_t compute_diff(uint8_t *image, uint16_t offX, uint16_t offY, uint16_t row_size)
{
uint16_t off = (offY   2) * row_size   (offX   2); // we calc only the 4x4 pattern
uint32_t acc;
//4*4畫素向下求差,再累加
acc = __USAD8 (*((uint32_t*) &image[off   0   0 * row_size]), *((uint32_t*) &image[off   0   1 * row_size]));
acc = __USADA8(*((uint32_t*) &image[off   0   1 * row_size]), *((uint32_t*) &image[off   0   2 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image[off   0   2 * row_size]), *((uint32_t*) &image[off   0   3 * row_size]), acc);
//4*4畫素向右求差,再累加
uint32_t col1 = (image[off   0   0 * row_size] << 24) | image[off   0   1 * row_size] << 16 | image[off   0   2 * row_size] << 8 | image[off   0   3 * row_size];
uint32_t col2 = (image[off   1   0 * row_size] << 24) | image[off   1   1 * row_size] << 16 | image[off   1   2 * row_size] << 8 | image[off   1   3 * row_size];
uint32_t col3 = (image[off   2   0 * row_size] << 24) | image[off   2   1 * row_size] << 16 | image[off   2   2 * row_size] << 8 | image[off   2   3 * row_size];
uint32_t col4 = (image[off   3   0 * row_size] << 24) | image[off   3   1 * row_size] << 16 | image[off   3   2 * row_size] << 8 | image[off   3   3 * row_size];
//全部累加
acc = __USADA8(col1, col2, acc);
acc = __USADA8(col2, col3, acc);
acc = __USADA8(col3, col4, acc);
return acc;
}
[color=rgb(51, 102, 153) !important]複製程式碼
///////////////////////////////////////////////////////
//函式功能:比較兩副8X8畫素圖片的相似度
///////////////////////////////////////////////////////
static inline uint32_t compute_sad_8x8(uint8_t *image1, uint8_t *image2, uint16_t off1X, uint16_t off1Y, uint16_t off2X, uint16_t off2Y, uint16_t row_size)
{
uint16_t off1 = off1Y * row_size   off1X; // image1
uint16_t off2 = off2Y * row_size   off2X; // image2
//兩副8*8畫素對應相減,再累加
uint32_t acc;
//第一行相減,再累加
acc = __USAD8 (*((uint32_t*) &image1[off1   0   0 * row_size]), *((uint32_t*) &image2[off2   0   0 * row_size]));
acc = __USADA8(*((uint32_t*) &image1[off1   4   0 * row_size]), *((uint32_t*) &image2[off2   4   0 * row_size]), acc);
//第二行相減,再累加,依次類推
acc = __USADA8(*((uint32_t*) &image1[off1   0   1 * row_size]), *((uint32_t*) &image2[off2   0   1 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   1 * row_size]), *((uint32_t*) &image2[off2   4   1 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   2 * row_size]), *((uint32_t*) &image2[off2   0   2 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   2 * row_size]), *((uint32_t*) &image2[off2   4   2 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   3 * row_size]), *((uint32_t*) &image2[off2   0   3 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   3 * row_size]), *((uint32_t*) &image2[off2   4   3 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   4 * row_size]), *((uint32_t*) &image2[off2   0   4 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   4 * row_size]), *((uint32_t*) &image2[off2   4   4 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   5 * row_size]), *((uint32_t*) &image2[off2   0   5 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   5 * row_size]), *((uint32_t*) &image2[off2   4   5 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   6 * row_size]), *((uint32_t*) &image2[off2   0   6 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   6 * row_size]), *((uint32_t*) &image2[off2   4   6 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   0   7 * row_size]), *((uint32_t*) &image2[off2   0   7 * row_size]), acc);
acc = __USADA8(*((uint32_t*) &image1[off1   4   7 * row_size]), *((uint32_t*) &image2[off2   4   7 * row_size]), acc);
return acc;
}
[color=rgb(51, 102, 153) !important]複製程式碼
然後每隔4個畫素來找特徵點
//上下左右迴圈移動4個畫素對比圖片相似度
for(int8_t yy=winmin; yy<=winmax; yy  )
{
for(int8_t xx=winmin; xx<=winmax; xx  )
{
//計算匹配度
temp_match = compute_sad_8x8(image_new, image_old, x, y, x   xx, y   yy, wid);
//尋找最小值,越小越相似
if (temp_match < match_min)
{
sumx = xx;
sumy = yy;
match_min = temp_match;
}
}
}

最後實際的效果還不錯 鐳射晶片VL53L0X一樣可以正常工作,對自己的焊工自豪一波
某寶地址:
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-17480225679.10.45b621d6iVdimZ&id=565436866230