学習目標:
python + opencvを使用して、特定の色の範囲を識別します
準備オーケー:
1.Pycharm開発環境2.Python
3.8.3
3. opencv4HSV基本色コンポーネント範囲
プログラムの説明:
目標は、色が黄色のオブジェクトを検出し、それらの重心と輪郭をマークすることです。黄色の設定の上限と下限は、HSV再印刷ブログの基本的な色成分の範囲に由来します(侵害は削除されます)。
検出画像は以下のとおりです(オンラインで見つかった写真、侵害は削除されます)。
プログラムは比較的単純で、主なプロセスは次の
とおりです。Videocaptureは画像を取得します-> setは画像サイズをリセットしてプログラム速度を上げます-> cvtColorをhsv画像形式に変換します-> inRange二値化-> medianBlur中央値フィルター- >腐食を侵食->拡張を拡張->輪郭を見つけるためのfindContours->最大の輪郭を見つけるためのmax->輪郭を含む最小の円を見つけるためのminEncloseingCircle->モーメントを計算するためのモーメント->計算するその瞬間からの図心->図心と円をマークする
コードは次のように表示されます。
import cv2 as cv
import numpy as np
import matplotlib as plt
import imutils
colorLower = (26, 43, 46) # 二值化下限
colorUpper = (34, 255, 255) # 二值化上限
cap = cv.VideoCapture(0)
# cap.set(3, 320) # 为快速运算,把图片变成缩小成320*240
# cap.set(4, 240)
kerne = np.ones((10, 10), np.uint8) # 开运算参数
while True:
ret, frame = cap.read() # 读取图像
# cv.namedWindow('frame', cv.WINDOW_AUTOSIZE)
# cv.imshow('frame', frame)
hsv = cv.cvtColor(frame.copy(), cv.COLOR_BGR2HSV) # 转化成hsv格式
# cv.namedWindow('hsv', cv.WINDOW_AUTOSIZE)
# cv.imshow('hsv', frame)
mask = cv.inRange(hsv.copy(), colorLower, colorUpper) # 根据范围二值化
# cv.namedWindow('mask', cv.WINDOW_AUTOSIZE)
# cv.imshow('mask', mask)
# # ################## 先开运算再滤波测试 ###################
# opening = cv.morphologyEx(mask.copy(), cv.MORPH_OPEN, kerne)
# cv.namedWindow('opening', cv.WINDOW_AUTOSIZE)
# cv.imshow('opening', opening)
#
# median = cv.medianBlur(opening.copy(), 3)
# cv.namedWindow('median', cv.WINDOW_AUTOSIZE)
# cv.imshow('median', median)
# # ########################################################
median = cv.medianBlur(mask.copy(), 3) # 中值滤波 去掉椒盐噪点,参数3表示中值运算方块3*3
# cv.namedWindow('median', cv.WINDOW_AUTOSIZE)
# cv.imshow('median', median)
# # ########################### 开运算(先腐蚀再运算) ###########################
# opening = cv.morphologyEx(median.copy(), cv.MORPH_OPEN, kerne) # 进行开运算
# cv.namedWindow('opening', cv.WINDOW_AUTOSIZE)
# cv.imshow('opening', opening)
# # ####################################################################
# ########################### 先腐蚀再膨胀 ###########################
erode = cv.erode(mask.copy(), None, iterations=2)
dilate = cv.dilate(erode.copy(), None, iterations=2)
# cv.namedWindow('dilate', cv.WINDOW_AUTOSIZE)
# cv.imshow('dilate', dilate)
# 开运算去掉的比较多
# #####################################################################
# 找轮廓
cnts = cv.findContours(mask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[-2]
center = None
# 如果在图中找到一定的轮廓就进行计算,否则不进行计算
if len(cnts) > 0:
c = max(cnts, key=cv.contourArea) # 找到图像中最大的轮廓
((x, y), radius) = cv.minEnclosingCircle(c) # 找到最小的圆包含这个轮廓,返回坐标和半径
M = cv.moments(c) # 计算图像的矩
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])) # 通过矩计算图像的质心
# 判断以下他的半径,太小的话就认为是噪声,就忽略掉
if radius > 10:
cv.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2) # 在检测到的轮廓周围画圆圈
cv.circle(frame, center, 5, (0, 0, 255), -1)
cv.namedWindow('frame', cv.WINDOW_AUTOSIZE)
cv.imshow('frame', frame)
if cv.waitKey(1) == 27: # 按下Esc键就停止
break
cap.release()
cv.destroyAllWindows()
関数の説明の一部
(以下の機能はすべて転載し、侵害を削除します(書き込みはとても良いです)
手順の説明
このプログラムでは、オープン操作など、多くの機能がコメント化されています。これらはすべて、プログラムをデバッグするときに、目視検査で最終的な効果に最適な方法を確認するためのものです。なぜこれを行ったのか、なぜガウスフィルタリングの代わりにメディアンフィルタリングを使用するのかと聞かれたら、これは私のチューニングの結果であるとしか言えません。私の知識はまだ非常に少なく、計算を通じてより良いアルゴリズムを直接見つけるだけでは十分ではありません。現在、私は常にデバッグ、パラメーターの変更、オンライン情報のチェックを行って、比較的優れた認識プロセスを見つけることに固執しています。