**非常詳細(xì)的視頻和文字教程,講解常見(jiàn)的openmv教程包括 巡線、物體識(shí)別、圓環(huán)識(shí)別、閾值自動(dòng)獲取等。非常適合學(xué)習(xí)openmv、K210、K230等項(xiàng)目
視頻合集鏈接在
openmv教程合集 openmv入門到項(xiàng)目開(kāi)發(fā) openmv和STM32通信 openmv和opencv區(qū)別 openmv巡線 openmv數(shù)字識(shí)別教程LCD
??痮penmv視覺(jué)文章鏈接:
https://blog.csdn.net/qq_46187594/category_12900902.html
5-識(shí)別可能的色塊的區(qū)域縮放-到和模板大小一樣
下面的思路和程序參考程歡歡大佬的作品(大佬視頻中使用的他的板子,所以程序是想要修改的 下面會(huì)提供修改好的,還有大佬是使用PS整理的想要模板,后面我會(huì)演示使用更簡(jiǎn)單的方法.視頻里面也有對(duì)優(yōu)化思路的講解可以看一下): https://www.bilibili.com/video/BV1G3411t7HX/?share_source=copy_web&vd_source=f5d5850ab773377dff308188468fbc77
程序思路:
先找色塊找到可能是數(shù)字的黑色色塊,
做縮放把黑色色塊尺寸縮放到和模板一樣,
簡(jiǎn)單方法制作統(tǒng)一40像素模板:
使用QQ或者微信等截圖工具把之前1-8數(shù)字截圖小一些,如下數(shù)字整個(gè)剛剛在框里面
然后使用win10系統(tǒng)自帶的編輯圖片工具打開(kāi)(win10是畫圖工具這個(gè)軟件,不確定win7或者win11里面編輯圖片的有這個(gè)功能,如果沒(méi)有自行下載ps等更專業(yè)軟件學(xué)習(xí)如何修改大小)
然后使用轉(zhuǎn)化網(wǎng)站,把剛剛的jpg格式轉(zhuǎn)成為pgm,可以使用的網(wǎng)站如下(如果都能用了,自行百度搜索一個(gè)可以的,如果網(wǎng)站讓你設(shè)置大小等你無(wú)需設(shè)置讓他保持默認(rèn)大小就行)JPG 到 PGM - 將您的 JPG 轉(zhuǎn)換為 PGM 的在線工具
JPG轉(zhuǎn)PGM批量轉(zhuǎn)換器 | 線上 免費(fèi)
把處理的好的復(fù)制到openmv里面
然后下面是程序
下面的程序會(huì)有一些問(wèn)題,在較新版固件比如4.5.9上 執(zhí)行下面代碼顯示在openmv IDE幀緩沖區(qū)的圖像沒(méi)有把數(shù)字圈出來(lái)(通過(guò)觀察串行端口 發(fā)現(xiàn)也已經(jīng)識(shí)別到了數(shù)字),而使用4.4.1固件數(shù)字會(huì)被圈出來(lái)也就是說(shuō)openmv IDE顯示的是處理繪制的圖像。
# -*- coding: utf-8 -*-
"""
OpenMV數(shù)字識(shí)別程序(彩色顯示版)
功能:識(shí)別攝像頭中的數(shù)字并用紅色字體標(biāo)注
特點(diǎn):保持灰度處理流程,最終輸出彩色標(biāo)注畫面
"""
# *************************** 硬件初始化部分 ***************************
# 導(dǎo)入機(jī)器視覺(jué)庫(kù)和時(shí)鐘模塊
import sensor, image, time
# 初始化攝像頭硬件
sensor.reset() # 復(fù)位攝像頭硬件,清空初始化參數(shù)
# 設(shè)置攝像頭采集模式(核心參數(shù)設(shè)置)
sensor.set_pixformat(sensor.RGB565) # 設(shè)置為彩色模式(16位RGB,每個(gè)像素2字節(jié))
sensor.set_framesize(sensor.QQVGA) # 分辨率160x120(用于保證處理速度)
sensor.set_contrast(3) # 設(shè)置對(duì)比度+3(增強(qiáng)明暗對(duì)比,提升識(shí)別率)
# *************************** 圖像鏡像設(shè)置 ***************************
# (根據(jù)攝像頭物理安裝方向調(diào)整,不需要可注釋)
sensor.set_vflip(True) # 垂直翻轉(zhuǎn):適用于攝像頭倒置安裝的情況
sensor.set_hmirror(True) # 水平鏡像:適用于需要鏡像顯示的場(chǎng)景
# *************************** 數(shù)字模板配置 ***************************
num_quantity = 8 # 定義要識(shí)別的數(shù)字范圍(1-8)
num_model = [] # 創(chuàng)建空列表存儲(chǔ)模板圖像
# 加載預(yù)存數(shù)字模板(需提前準(zhǔn)備1.pgm~8.pgm文件)
for n in range(1, num_quantity+1):
# 加載PGM格式模板(建議使用白底黑字40像素高度圖片)
num_model.append(image.Image(str(n) + '.pgm')) # 將模板圖像存入列表
# *************************** 性能監(jiān)測(cè)配置 ***************************
clock = time.clock() # 創(chuàng)建幀率計(jì)算時(shí)鐘對(duì)象
# *************************** 圖像緩沖區(qū)配置 ***************************
# 分配模板匹配專用緩沖區(qū)(優(yōu)化處理速度)
img_to_matching = sensor.alloc_extra_fb(35, 45, sensor.GRAYSCALE) # 35x45灰度緩沖區(qū)
# 說(shuō)明:該緩沖區(qū)用于存儲(chǔ)縮放后的待匹配區(qū)域圖像
# *************************** 算法參數(shù)設(shè)置 ***************************
threshold = (0, 70) # 灰度閾值范圍:0-70(用于檢測(cè)深色數(shù)字區(qū)域)
scale = 1 # 圖像縮放比例初始化值
# *************************** 主循環(huán)處理邏輯 ***************************
while(True):
# 【階段1】幀率計(jì)算與圖像采集
clock.tick() # 開(kāi)始幀計(jì)時(shí)(必須在循環(huán)開(kāi)頭調(diào)用)
img = sensor.snapshot() # 捕獲一幀RGB565彩色圖像(160x120像素)
# 【階段2】創(chuàng)建灰度處理副本
img_gray = img.to_grayscale(copy=True) # 生成灰度副本(保持原圖不變)
# 注意:所有圖像處理操作在灰度副本上進(jìn)行以保證算法穩(wěn)定性
# 【階段3】色塊檢測(cè)
blobs = img_gray.find_blobs([threshold]) # 在灰度圖像中查找符合閾值的色塊
# 【階段4】候選區(qū)域處理
if blobs: # 如果檢測(cè)到有效色塊
# 遍歷所有檢測(cè)到的色塊(blobs對(duì)象包含多個(gè)blob)
for blob in blobs:
# 色塊有效性過(guò)濾條件(排除噪聲干擾)
if blob.pixels() > 50 and 100 > blob.h() > 10 and blob.w() > 3:
# 【步驟4.1】在彩色圖像上繪制檢測(cè)框
# 繪制綠色預(yù)備框(比實(shí)際區(qū)域大4像素)
img.draw_rectangle(
blob.x()-2, blob.y()-2, # 起點(diǎn)坐標(biāo)(左上角)
blob.w()+4, blob.h()+4, # 框體尺寸(寬度+高度)
color=(0, 255, 0) # 顏色:純綠色
)
# 在色塊左上角顯示當(dāng)前縮放比例(調(diào)試信息,白色文字)
img.draw_string(blob[0], blob[1], str(round(scale, 2)), color=(255, 255, 255))
# 【步驟4.2】計(jì)算縮放比例
scale = 40 / blob.h() # 根據(jù)色塊高度計(jì)算縮放比例(模板高度為40像素)
# 【步驟4.3】提取待匹配區(qū)域
img_to_matching.draw_image(
img_gray, # 源圖像(使用灰度副本保證處理一致性)
0, 0, # 目標(biāo)位置(緩沖區(qū)左上角)
roi=( # 源圖像感興趣區(qū)域(Region of Interest)
blob.x()-2, # x起點(diǎn)(左擴(kuò)2像素)
blob.y()-2, # y起點(diǎn)(上擴(kuò)2像素)
blob.w()+4, # 寬度(左右各擴(kuò)2像素)
blob.h()+4 # 高度(上下各擴(kuò)2像素)
),
x_scale=scale, # 水平縮放比例
y_scale=scale # 垂直縮放比例
)
# 【階段5】模板匹配識(shí)別
# 遍歷所有數(shù)字模板進(jìn)行匹配
for n in range(0, num_quantity):
# 執(zhí)行模板匹配(核心識(shí)別函數(shù))
r = img_to_matching.find_template(
num_model[n], # 當(dāng)前數(shù)字模板(n對(duì)應(yīng)數(shù)字1-8)
0.7, # 相似度閾值(0.0-1.0,越大匹配越嚴(yán)格)
step=2, # 搜索步長(zhǎng)(2表示隔行掃描,加快速度)
search=image.SEARCH_EX # 搜索模式:窮舉搜索(精度最高)
)
if r: # 如果匹配結(jié)果有效(相似度超過(guò)閾值)
# 【步驟5.1】在彩色圖像上繪制橙色確認(rèn)框
img.draw_rectangle(
blob[0:4], # 矩形參數(shù)(x,y,w,h)
color=(255, 100, 0) # 橙色邊框(BGR格式)
)
# 【步驟5.2】顯示識(shí)別結(jié)果(核心修改點(diǎn))
img.draw_string(
blob[0], blob[1], # 顯示位置(色塊左上角)
str(n+1), # 顯示內(nèi)容(識(shí)別到的數(shù)字)
scale=5, # 字體放大倍數(shù)(原始5倍)
color=(255, 0, 0) # 字體顏色:純紅色(BGR格式)
)
# 【新增】輸出識(shí)別結(jié)果:數(shù)字ID,X坐標(biāo),Y坐標(biāo)
print("DETECT: num={}, x={}, y={}".format(n+1, blob.cx(), blob.cy()))
# 【階段6】顯示幀率信息
# 在畫面左上角顯示當(dāng)前幀率(白色文字)
img.draw_string(0, 0, str(round(clock.fps(), 2)), color=(255, 255, 255))
# *************************** 注意事項(xiàng) ***************************
"""
1. 必須準(zhǔn)備數(shù)字模板:在存儲(chǔ)卡根目錄放置1.pgm~8.pgm文件
2. 模板建議規(guī)格:白底黑字、高度40像素、PGM格式
3. 實(shí)際顯示效果:
- 綠色框:初步檢測(cè)區(qū)域
- 橙色框:成功匹配區(qū)域
- 紅色數(shù)字:識(shí)別結(jié)果
- 白色文字:幀率信息
4. 性能參數(shù):QQVGA分辨率下典型幀率15-30fps(取決于處理復(fù)雜度)
5. 調(diào)試技巧:可通過(guò)調(diào)整threshold閾值和scale計(jì)算優(yōu)化識(shí)別效果
"""
下面的代碼 解決顯示問(wèn)題:
使用img.copy 可以復(fù)制一份圖像方便openmv IDE顯示和后面處理圖像
img_copy = img.copy()#img復(fù)制到img_copy上一份 兩個(gè)參數(shù)分別是
# -*- coding: utf-8 -*-
"""
OpenMV數(shù)字識(shí)別程序(彩色顯示版)
功能:識(shí)別攝像頭中的數(shù)字并用紅色字體標(biāo)注
特點(diǎn):保持灰度處理流程,最終輸出彩色標(biāo)注畫面
"""
# *************************** 硬件初始化部分 ***************************
# 導(dǎo)入機(jī)器視覺(jué)庫(kù)和時(shí)鐘模塊
import sensor, image, time
# 初始化攝像頭硬件
sensor.reset() # 復(fù)位攝像頭硬件,清空初始化參數(shù)
# 設(shè)置攝像頭采集模式(核心參數(shù)設(shè)置)
sensor.set_pixformat(sensor.RGB565) # 設(shè)置為彩色模式(16位RGB,每個(gè)像素2字節(jié))
sensor.set_framesize(sensor.QQVGA) # 分辨率160x120(用于保證處理速度)
sensor.set_contrast(3) # 設(shè)置對(duì)比度+3(增強(qiáng)明暗對(duì)比,提升識(shí)別率)
# *************************** 圖像鏡像設(shè)置 ***************************
# (根據(jù)攝像頭物理安裝方向調(diào)整,不需要可注釋)
sensor.set_vflip(True) # 垂直翻轉(zhuǎn):適用于攝像頭倒置安裝的情況
sensor.set_hmirror(True) # 水平鏡像:適用于需要鏡像顯示的場(chǎng)景
# *************************** 數(shù)字模板配置 ***************************
num_quantity = 8 # 定義要識(shí)別的數(shù)字范圍(1-8)
num_model = [] # 創(chuàng)建空列表存儲(chǔ)模板圖像
# 加載預(yù)存數(shù)字模板(需提前準(zhǔn)備1.pgm~8.pgm文件)
for n in range(1, num_quantity+1):
# 加載PGM格式模板(建議使用白底黑字40像素高度圖片)
num_model.append(image.Image(str(n) + '.pgm')) # 將模板圖像存入列表
# *************************** 性能監(jiān)測(cè)配置 ***************************
clock = time.clock() # 創(chuàng)建幀率計(jì)算時(shí)鐘對(duì)象
# *************************** 圖像緩沖區(qū)配置 ***************************
# 分配模板匹配專用緩沖區(qū)(優(yōu)化處理速度)
img_to_matching = sensor.alloc_extra_fb(35, 45, sensor.GRAYSCALE) # 35x45灰度緩沖區(qū)
# 說(shuō)明:該緩沖區(qū)用于存儲(chǔ)縮放后的待匹配區(qū)域圖像
# *************************** 算法參數(shù)設(shè)置 ***************************
threshold = (0, 70) # 灰度閾值范圍:0-70(用于檢測(cè)深色數(shù)字區(qū)域)
scale = 1 # 圖像縮放比例初始化值
# *************************** 主循環(huán)處理邏輯 ***************************
while(True):
# 【階段1】幀率計(jì)算與圖像采集
clock.tick() # 開(kāi)始幀計(jì)時(shí)(必須在循環(huán)開(kāi)頭調(diào)用)
img = sensor.snapshot() # 捕獲一幀RGB565彩色圖像(160x120像素)
img_copy = img.copy()#img復(fù)制到img_copy上一份 兩個(gè)參數(shù)分別是
#這樣操作更方便后面 openmvIDE幀緩沖區(qū)顯示的是img 圖像,后面如果比如訓(xùn)練可以使用彩色的img_copy 進(jìn)行循跡
# 【階段2】創(chuàng)建灰度處理副本
#img_gray = img.to_grayscale(copy=True, allocator=image.ALLOCATOR_CB)
img_gray = img_copy.to_grayscale(copy=True) # 生成灰度副本(保持原圖不變)
# 注意:所有圖像處理操作在灰度副本上進(jìn)行以保證算法穩(wěn)定性
# 【階段3】色塊檢測(cè)
blobs = img_gray.find_blobs([threshold]) # 在灰度圖像中查找符合閾值的色塊
# 【階段4】候選區(qū)域處理
if blobs: # 如果檢測(cè)到有效色塊
# 遍歷所有檢測(cè)到的色塊(blobs對(duì)象包含多個(gè)blob)
for blob in blobs:
# 色塊有效性過(guò)濾條件(排除噪聲干擾)
if blob.pixels() > 50 and 100 > blob.h() > 10 and blob.w() > 3:
# 【步驟4.1】在彩色圖像上繪制檢測(cè)框
# 繪制綠色預(yù)備框(比實(shí)際區(qū)域大4像素)
img.draw_rectangle(
blob.x()-2, blob.y()-2, # 起點(diǎn)坐標(biāo)(左上角)
blob.w()+4, blob.h()+4, # 框體尺寸(寬度+高度)
color=(0, 255, 0) # 顏色:純綠色
)
# 在色塊左上角顯示當(dāng)前縮放比例(調(diào)試信息,白色文字)
img.draw_string(blob[0], blob[1], str(round(scale, 2)), color=(255, 255, 255))
# 【步驟4.2】計(jì)算縮放比例
scale = 40 / blob.h() # 根據(jù)色塊高度計(jì)算縮放比例(模板高度為40像素)
# 【步驟4.3】提取待匹配區(qū)域
img_to_matching.draw_image(
img_gray, # 源圖像(使用灰度副本保證處理一致性)
0, 0, # 目標(biāo)位置(緩沖區(qū)左上角)
roi=( # 源圖像感興趣區(qū)域(Region of Interest)
blob.x()-2, # x起點(diǎn)(左擴(kuò)2像素)
blob.y()-2, # y起點(diǎn)(上擴(kuò)2像素)
blob.w()+4, # 寬度(左右各擴(kuò)2像素)
blob.h()+4 # 高度(上下各擴(kuò)2像素)
),
x_scale=scale, # 水平縮放比例
y_scale=scale # 垂直縮放比例
)
# 【階段5】模板匹配識(shí)別
# 遍歷所有數(shù)字模板進(jìn)行匹配
for n in range(0, num_quantity):
# 執(zhí)行模板匹配(核心識(shí)別函數(shù))
r = img_to_matching.find_template(
num_model[n], # 當(dāng)前數(shù)字模板(n對(duì)應(yīng)數(shù)字1-8)
0.7, # 相似度閾值(0.0-1.0,越大匹配越嚴(yán)格)
step=2, # 搜索步長(zhǎng)(2表示隔行掃描,加快速度)
search=image.SEARCH_EX # 搜索模式:窮舉搜索(精度最高)
)
if r: # 如果匹配結(jié)果有效(相似度超過(guò)閾值)
# 【步驟5.1】在彩色圖像上繪制橙色確認(rèn)框
img.draw_rectangle(
blob[0:4], # 矩形參數(shù)(x,y,w,h)
color=(255, 100, 0) # 橙色邊框(BGR格式)
)
# 【步驟5.2】顯示識(shí)別結(jié)果(核心修改點(diǎn))
img.draw_string(
blob[0], blob[1], # 顯示位置(色塊左上角)
str(n+1), # 顯示內(nèi)容(識(shí)別到的數(shù)字)
scale=5, # 字體放大倍數(shù)(原始5倍)
color=(255, 0, 0) # 字體顏色:純紅色(BGR格式)
)
# 【新增】輸出識(shí)別結(jié)果:數(shù)字ID,X坐標(biāo),Y坐標(biāo)
print("DETECT: num={}, x={}, y={}".format(n+1, blob.cx(), blob.cy()))
# 【階段6】顯示幀率信息
# 在畫面左上角顯示當(dāng)前幀率(白色文字)
img.draw_string(0, 0, str(round(clock.fps(), 2)), color=(255, 255, 255))