Hough変換で直線、円検出をやってみる
import cv2 import numpy as np img = cv2.imread('dave.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray,50,150,apertureSize = 3) lines = cv2.HoughLines(edges,1,np.pi/180,200) for rho,theta in lines[0]: a = np.cos(theta) b = np.sin(theta) x0 = a*rho y0 = b*rho x1 = int(x0 + 1000*(-b)) y1 = int(y0 + 1000*(a)) x2 = int(x0 - 1000*(-b)) y2 = int(y0 - 1000*(a)) cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2) cv2.imwrite('houghlines3.jpg',img)
第1引数は入力画像であり,2値画像でなければなりません.あらかじめ2値化やエッジ検出をした画像を使うと良いでしょう
第2,3引数にはそれぞれ \rho と \theta の精度を指定します.
第4引数は,直線とみなされるのに必要な最低限の投票数を意味するしきい値
確率的ハフ変換による直線検出
import cv2 import numpy as np img = cv2.imread('dave.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray,50,150,apertureSize = 3) minLineLength = 100 maxLineGap = 10 lines = cv2.HoughLinesP(edges,1,np.pi/180,10,minLineLength,maxLineGap) for x1,y1,x2,y2 in lines[0]: cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) cv2.imwrite('houghlines.jpg',img)
参考:ハフ変換による直線検出 — OpenCV-Python Tutorials 1 documentation
特徴検出 — opencv 2.2 documentation
円検出
circles = cv2.HoughCircles(image, cv2.HOUGH_GRADIENT, dp=2, minDist=20, param1=20, param2=20, minRadius=6, maxRadius=20 )
パラメータ
dp ・・・ 処理するときに元画像の解像度の倍率.1だとそのままの画質で処理
minDist ・・・ 検出される円と円の最小距離
param1 ・・・ 低いほどいろんなエッジを検出
param2 ・・・ 低いほど円じゃないものも検出
minRadius ・・・ 最小半径
maxRadius ・・・ 最大半径
動作確認用雑なコード↓
import cv2 import numpy as np cap = cv2.VideoCapture(0) while(1): # Take each frame _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_light_pink = np.array([168, 50, 50]) upper_light_pink = np.array([188, 255, 255]) mask = cv2.inRange(hsv, lower_light_pink, upper_light_pink) circles = cv2.HoughCircles(mask,cv2.HOUGH_GRADIENT,1,20, param1=50,param2=20,minRadius=0,maxRadius=0) if circles is None: cv2.imshow('frame',frame) k = cv2.waitKey(5) & 0xFF if k == 27: break pass else: circles = np.uint16(np.around(circles)) circle = [] x = [] y = [] for i in circles[0,:]: x.append(i[0]) y.append(i[1]) circle.append(i[2]) idx = circle.index(max(circle)) cv2.circle(frame,(x[idx],y[idx]),circle[idx],(0,255,0),2) cv2.imshow('frame',frame) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows()
所感
円検出のパラメータ調整難しい…
参考: 円の検出 - TB-code
Opencvの円検出についてOpencvで円検出をするのですが、表示された画像の、... - Yahoo!知恵袋
Python cv2.HoughCircles で円検出 – LLC DigiFie Good!
↑c++とframe rateの高いカメラを使えばもう少し円検出の速度が挙げれるみたい。。。