1 簡介
Opencv(Open Source Computer Vision Library)是一個基于開源發(fā)行的跨平臺計算機視覺庫,它實現(xiàn)了圖像處理和計算機視覺方面的很多通用算法,已成為計算機視覺領(lǐng)域最有力的研究工具。在深度學(xué)習(xí)中,我們會經(jīng)常接觸到兩個名稱,圖像處理和計算機視覺,它們之間有什么區(qū)別呢?圖像處理 (Image Processing)
目的:圖像處理主要集中在改善或轉(zhuǎn)換圖像的質(zhì)量,使得圖像更適合人類觀察或者為后續(xù)的分析做準(zhǔn)備。
方法:通常涉及像素級別的操作,比如調(diào)整亮度、對比度、顏色校正、濾波(如高斯模糊、中值濾波去噪)、邊緣檢測、形態(tài)學(xué)變換(膨脹、腐蝕)等。
計算機視覺 (Computer Vision)
目的:計算機視覺的目標(biāo)是使計算機能夠理解和解釋圖像或視頻的內(nèi)容,實現(xiàn)類似于人類視覺系統(tǒng)的感知能力。
方法:使用高級算法來解析圖像中的內(nèi)容,包括但不限于特征提取、物體識別、分類、跟蹤、場景重建等。這可能涉及到機器學(xué)習(xí)和深度學(xué)習(xí)模型的應(yīng)用。
簡而言之,圖像處理是計算機視覺的基礎(chǔ),提供了必要的工具和技術(shù)來預(yù)處理和優(yōu)化圖像數(shù)據(jù);而計算機視覺則是在此基礎(chǔ)之上,通過更加復(fù)雜的算法和模型來解析圖像的意義。在實際應(yīng)用中,這兩者往往是緊密結(jié)合的,共同作用于解決復(fù)雜的問題。例如,在一個自動駕駛系統(tǒng)中,圖像處理可能會用于清理傳感器輸入的數(shù)據(jù),而計算機視覺則負(fù)責(zé)識別道路上的行人、車輛和其他重要元素。
2 基礎(chǔ)知識
OpenCV 是一個開源的計算機視覺和機器學(xué)習(xí)軟件庫,廣泛用于圖像處理、視頻捕捉、物體檢測等領(lǐng)域。一些常用操作及其目的:
讀取圖片
使用cv2.imread()函數(shù)加載圖像。
目的:為后續(xù)處理和分析準(zhǔn)備圖像數(shù)據(jù)。
轉(zhuǎn)換色彩空間
使用cv2.cvtColor()進(jìn)行色彩空間轉(zhuǎn)換。
目的:適應(yīng)不同算法的需求,例如灰度圖用于簡化計算,HSV用于顏色分割等。
濾波
高斯模糊 (cv2.GaussianBlur)、均值濾波 (cv2.blur) 和雙邊濾波 (cv2.bilateralFilter) 等。
目的:降噪和平滑圖像,或在保持邊緣的同時模糊細(xì)節(jié)。
繪制圖形
使用cv2.line()、cv2.rectangle()、cv2.circle()和cv2.polylines()來繪制直線、矩形、圓形或多邊形。
目的:可視化結(jié)果,標(biāo)注圖像中的特征或者創(chuàng)建掩碼。
邊緣檢測
Canny 邊緣檢測 (cv2.Canny) 或 Sobel 操作符 (cv2.Sobel)。
目的:檢測圖像中物體的邊界,是很多高級計算機視覺任務(wù)的基礎(chǔ)步驟。
閾值操作
cv2.threshold()用于二值化圖像。
目的:突出顯示感興趣區(qū)域,簡化圖像以利于進(jìn)一步分析。
Sobel 濾波
使用cv2.Sobel()計算圖像梯度。
目的:增強邊緣,通常與邊緣檢測相關(guān)聯(lián)。
文件保存
cv2.imwrite()將圖像保存到磁盤。
目的:保存處理后的圖像以便將來使用或分享。
此外,還有其他重要的OpenCV功能,如:
直方圖均衡化(cv2.equalizeHist) 提升圖像對比度。
模板匹配(cv2.matchTemplate) 用于查找一個圖像中的另一個小圖像的位置。
特征點檢測和描述子計算,如 SIFT, SURF, ORB 等,用于圖像配準(zhǔn)、拼接等任務(wù)。
這些基礎(chǔ)操作和高級特性共同構(gòu)成了強大的工具集,可以用來開發(fā)從簡單的圖像編輯應(yīng)用到復(fù)雜的計算機視覺系統(tǒng)。 這些操作是構(gòu)建復(fù)雜圖像處理流水線的基礎(chǔ),可以單獨使用,也可以組合起來解決更復(fù)雜的視覺問題。例如,預(yù)處理階段可能會包括去噪、邊緣檢測和形態(tài)學(xué)操作;而在后處理階段,則可能會涉及閾值操作和繪制幾何圖形來標(biāo)注或解釋結(jié)果。以上這些算子僅僅是OpenCV庫的一小部分的內(nèi)容,但是它們是支持我們進(jìn)行復(fù)雜操作的基礎(chǔ)。
3 實際操作
在學(xué)習(xí)OpenCV的初期,可能會覺得每個算子或函數(shù)就像是獨立的知識點,雖然能夠理解它們各自的功能和用法,但當(dāng)面對實際問題時,卻難以將這些知識點有效地組合起來解決問題。這是因為從理論到實踐的應(yīng)用需要一個過渡的過程,在這個過程中,不僅需要掌握單個算子的操作,還需要學(xué)會如何根據(jù)具體的需求選擇合適的算子,并且合理地調(diào)整參數(shù)以達(dá)到預(yù)期的效果。OpenCV的強大之處在于它提供了豐富的圖像處理功能,但這也意味著使用它的難點在于:
理解和記憶大量的算子:OpenCV庫中包含了大量的算子,每個算子都有其特定的應(yīng)用場景和參數(shù)設(shè)置。對于初學(xué)者來說,理解和記住這么多的內(nèi)容可能是一個挑戰(zhàn)。
算子之間的組合應(yīng)用:很多情況下,單獨使用一個算子并不能完成復(fù)雜的任務(wù),而是需要多個算子相互配合。這就要求學(xué)習(xí)者不僅要了解各個算子的工作原理,還要懂得如何將它們有機地結(jié)合起來,以實現(xiàn)更復(fù)雜的功能。
參數(shù)調(diào)優(yōu):每個算子通常都帶有一系列可調(diào)節(jié)的參數(shù),這些參數(shù)的選擇直接影響到最終的結(jié)果。找到一組最優(yōu)化的參數(shù)值往往需要通過不斷的實驗和嘗試,這既考驗?zāi)托囊部简灲?jīng)驗。
解決實際問題的能力:將理論知識應(yīng)用于實踐,解決真實世界中的問題是學(xué)習(xí)任何技術(shù)的關(guān)鍵。對于OpenCV而言,這意味著要能夠分析給定的任務(wù)需求,確定所需的操作步驟,并正確地執(zhí)行這些步驟。為了克服上述困難,建議多做練習(xí),特別是針對不同類型的圖像處理任務(wù)進(jìn)行實戰(zhàn)演練。同時,可以參考官方文檔、在線教程以及社區(qū)討論來加深對算子的理解,學(xué)習(xí)他人是如何解決問題的。此外,不斷積累經(jīng)驗和案例研究也會有助于提高解決新問題的能力。
本文章主要講述如何在邊緣端設(shè)備上使用OpenCV。本次使用的邊緣端設(shè)備是凌智電子開發(fā)的凌智視覺模塊,具體如下:
如對該邊緣端設(shè)備感興趣,可到Gitee倉庫:凌智視覺模塊查看該設(shè)備的具體信息。
接下來我們通過幾個例子來介紹如何在邊緣端設(shè)備使用OpenCV進(jìn)行形狀檢測。
3.1 矩形檢測
importlockzhiner_vision_module.cv2ascv2fromlockzhiner_vision_module.editimportEditimporttimeimportsysif__name__ =="__main__": args = sys.argv iflen(args) !=3: print("Need model path. Example: python test_capture.py width height") exit(1) edit = Edit() edit.start_and_accept_connection() video_capture = cv2.VideoCapture() video_capture.set_width(int(args[1])) video_capture.set_height(int(args[2])) ifvideo_capture.open(0)isFalse: print("Failed to open capture") exit(1) whileTrue: read_index =0 total_time_ms =0 foriinrange(30): start_time = time.time() ret, mat = video_capture.read() ifretisFalse: continue end_time = time.time() # 轉(zhuǎn)換為灰度圖像 gray = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY) # 高斯模糊 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 二值化 _, binary = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY_INV) edges = cv2.Canny(binary, 30, 200) contours, _ = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # 近似輪廓 # 計算輪廓周長 epsilon = 0.02 * cv2.arcLength(contour, True) # 將輪廓近似為多邊形 if epsilon < 15:? ? ? ? ? ? ? ? ? ? continue? ? ? ? ? ? ? ? approx = cv2.approxPolyDP(contour, epsilon, True)? ? ? ? ? ? ? ? # 如果近似輪廓有4個頂點,則認(rèn)為是矩形? ? ? ? ? ? ? ? if len(approx) == 4:? ? ? ? ? ? ? ? ? ? cv2.putText(mat, "Rectangle", (50,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)? ? ? ? ? ? ? ? ? ? cv2.drawContours(mat, [approx], -1, (0, 255, 0), 2)? ? ? ? ? ? edit.print(mat)? ? ? ? ? ? total_time_ms += end_time - start_time? ? ? ? ? ? read_index += 1? ? ? ? print(f"FPS is {1.0 / (total_time_ms / read_index)}")
在這一段代碼中的檢測效果如下圖所示

但是當(dāng)我們只想要外部的矩形時,我們可以怎么做呢?
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

效果如上圖所示,接下來我們就得深究一下cv2.findContours mode 參數(shù) 和 method 參數(shù)的區(qū)別及作用了,我就不一一演示了,大家伙可以自行實驗,畢竟我也踩過。mode: 輪廓檢索模式,定義了如何檢索輪廓及其層次結(jié)構(gòu)。有以下幾種選擇:
cv2.RETR_EXTERNAL: 只檢索最外層的輪廓。
cv2.RETR_LIST: 檢索所有的輪廓,但不建立它們之間的等級關(guān)系。
cv2.RETR_CCOMP: 檢索所有的輪廓,并將它們組織為兩級層次結(jié)構(gòu):頂層是外部邊界,次級是孔洞。
cv2.RETR_TREE: 檢索所有輪廓,并重建完整的包含關(guān)系。
method: 輪廓近似方法,決定了輪廓的精度。有以下幾種選擇:
cv2.CHAIN_APPROX_NONE: 存儲所有的輪廓點,即沒有近似。
cv2.CHAIN_APPROX_SIMPLE: 壓縮水平、垂直和對角方向上的元素,只保留端點。
cv2.CHAIN_APPROX_TC89_L1: 使用一種稱為 Teh-Chin 鏈逼近算法的更復(fù)雜的壓縮方式。
cv2.CHAIN_APPROX_TC89_KCOS: 同樣使用 Teh-Chin 鏈逼近算法,但與 L1 不同,它是基于 KCOS 的。
3.2 圓形檢測
OpenCV 提供了HoughCircles函數(shù)來檢測圓形。Hough變換是一種用于從圖像中提取幾何形狀(如直線、圓等)的技術(shù),它通過參數(shù)空間的投票機制來實現(xiàn)。對于圓形檢測,Hough變換可以識別出滿足特定條件的圓形結(jié)構(gòu)。下面是使用 OpenCV 進(jìn)行圓形檢測的基本步驟:
首先加載需要檢測圓的圖像,并將其轉(zhuǎn)換為灰度圖,因為顏色信息對于圓形檢測不是必要的。調(diào)用cv2.HoughCircles函數(shù)進(jìn)行圓形檢測。該函數(shù)接受幾個重要參數(shù):
method:定義了檢測方法,通常使用cv2.HOUGH_GRADIENT。
dp:累加器分辨率與圖像分辨率的反比。dp=1 表示累加器具有與輸入圖像相同的分辨率。
minDist:檢測到的圓心之間的最小距離。如果設(shè)置得太小,可能會檢測到多個相鄰的圓;如果太大,可能會漏檢一些圓。
param1:Canny邊緣檢測的高閾值,低閾值是高閾值的一半。
param2:累加器閾值。該閾值越小,檢測到的圓越多(包括不完美的圓)。越大則只檢測到更明顯的圓。
minRadius和maxRadius:分別為檢測到的圓的最小和最大半徑。
請注意,上述參數(shù) (dp,minDist,param1,param2,minRadius,maxRadius) 需要根據(jù)具體應(yīng)用場景調(diào)整,以獲得最佳檢測效果。例如,不同的光照條件、背景復(fù)雜度或者目標(biāo)圓的大小都會影響這些參數(shù)的選擇。實例代碼
fromlockzhiner_vision_module.cv2importVideoCaptureimportlockzhiner_vision_module.cv2ascv2fromlockzhiner_vision_module.editimportEditimporttimeimportsyspi =3.14159265358979323846if__name__ =="__main__": args = sys.argv iflen(args) !=3: print("Need model path. Example: python test_capture.py width height") exit(1) edit = Edit() edit.start_and_accept_connection() video_capture = VideoCapture() video_capture.set_width(int(args[1])) video_capture.set_height(int(args[2])) ifvideo_capture.open(0)isFalse: print("Failed to open capture") exit(1) whileTrue: read_index =0 total_time_ms =0 foriinrange(30): start_time = time.time() ret, mat = video_capture.read() ifretisFalse: continue end_time = time.time() # 轉(zhuǎn)換為灰度圖像 # 轉(zhuǎn)換為灰度圖像 gray = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY) # 使用高斯模糊減少噪聲 blurred = cv2.GaussianBlur(gray, (9, 9), 2) # 使用 HoughCircles 檢測圓形 circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=50, param1=50, param2=30, minRadius=120, maxRadius=250) # print(circles) if circles is not None: # 在圖像上繪制檢測到的圓 for i in circles[0]: center = (int(i[0]), int(i[1])) radius = int(i[2]) cv2.putText(mat, "circle", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) # 繪制圓心 cv2.circle(mat, center, 1, (0, 100, 100), 3) # 繪制圓 cv2.circle(mat, center, radius, (0, 255, 0), 3) edit.print(mat) total_time_ms += end_time - start_time read_index += 1 print(f"FPS is {1.0 / (total_time_ms/read_index)}")
檢測效果圖 :

-
圖像處理
+關(guān)注
關(guān)注
27文章
1326瀏覽量
57873 -
AI
+關(guān)注
關(guān)注
88文章
34765瀏覽量
276924 -
OpenCV
+關(guān)注
關(guān)注
32文章
642瀏覽量
42639
發(fā)布評論請先 登錄
邊緣AI實現(xiàn)的核心環(huán)節(jié):硬件選擇和模型部署
Deepseek海思SD3403邊緣計算AI產(chǎn)品系統(tǒng)
AI模型部署邊緣設(shè)備的奇妙之旅:視覺巡線

【幸狐Omni3576邊緣計算套件試用體驗】DeepSeek 部署及測試
添越智創(chuàng)基于 RK3588 開發(fā)板部署測試 DeepSeek 模型全攻略
研華邊緣AI Box MIC-ATL3S部署Deepseek R1模型

AI模型部署邊緣設(shè)備的奇妙之旅:邊緣端設(shè)備的局域網(wǎng)視頻流傳輸方案
AI模型部署邊緣設(shè)備的奇妙之旅:邊緣端設(shè)備的局域網(wǎng)視頻流傳輸方案

AI模型部署邊緣設(shè)備的奇妙之旅:目標(biāo)檢測模型
AI模型部署邊緣設(shè)備的奇妙之旅:目標(biāo)檢測模型

評論