OpenCV学習+共通関数記録③:ホーフ変換と輪郭抽出
23593 ワード
OpenCVホフ変換と輪郭抽出 3. ホフ変換 3.1ホフ直線 3.2ホフ円 4. 輪郭抽出 4.1輪郭検索 4.2描画輪郭
3.ホフ変換
まずホフ変換公式ドキュメントを置きます:[ホフ直線変換公式ドキュメント]
3.1ホフ直線
3.2ホフ円
4.輪郭抽出画像エッジ抽出または二値化に基づく対象輪郭探索 エッジ抽出の閾値が最終的に輪郭発見結果に影響する 主要APIは以下の2つ
4.1輪郭の検索
輪郭検索モード:
輪郭検索アルゴリズム:
4.2輪郭の描画
実装手順:画像を読み取る 1枚グレーにして 画像の二値化処理 findContoursで輪郭を探す 輪郭の処理
3.ホフ変換
まずホフ変換公式ドキュメントを置きます:[ホフ直線変換公式ドキュメント]
3.1ホフ直線
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# 1.
img = cv.imread("../img/weiqi.jpg", cv.IMREAD_COLOR)
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2.
_, thresh_img = cv.threshold(gray_img, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
# 3.
# ,double , 1.0
rho = 1
# , numpy.pi/180( )
theta = np.pi / 180
# ,int , , , , 。( )
threshold = 10
#
min_line_length = 25
# ( ), , , , ,
max_line_gap = 3
lines = cv.HoughLinesP(thresh_img, rho, theta, threshold, minLineLength=min_line_length, maxLineGap=max_line_gap)
dst_img = img.copy()
for line in lines:
x1, y1, x2, y2 = line[0]
cv.line(dst_img, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv.imshow("src", img)
cv.imshow("gray_img", gray_img)
cv.imshow("thresh_img", thresh_img)
cv.imshow("dst_img", dst_img)
cv.waitKey(0)
3.2ホフ円
import cv2 as cv
import numpy as np
# 1.
img = cv.imread("../img/weiqi.jpg", cv.IMREAD_COLOR)
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2.
def hough_circle(gray_img):
# 。 cv2.HOUGH_GRADIENT
method = cv.HOUGH_GRADIENT
# 。 , dp = 1, 。 dp = 2, 。
dp = 1
# 。 minDist , 。 minDist , 。
minDist = 20
# param1 Canny
# param2 cv2.HOUGH_GRADIENT 。 , 。
# minRadius : , ,
# maxRadius : , ,
circles = cv.HoughCircles(gray_img, method, dp, minDist=minDist, param1=70, param2=30, minRadius=0, maxRadius=20)
dst_img = img.copy()
for circle in circles[0, :]:
# ,
x, y, r = circle
#
cv.circle(dst_img, (x, y), 2, (0, 255, 0), 1)
#
cv.circle(dst_img, (x, y), r, (0, 0, 255), 2)
cv.imshow("src", img)
cv.imshow("result", dst_img)
# 3. ,
hough_circle(gray_img)
cv.waitKey(0)
cv.destroyAllWindows()
4.輪郭抽出
findContours
輪郭発見drawContours
描画輪郭4.1輪郭の検索
, , = cv.findContours( , , )
# hierarchy[i][3], i 、 、 、
輪郭検索モード:
RETR_EXTERNAL
最外層プロファイルのみ検出RETR_LIST
すべてのプロファイルを抽出しリストに配置し、検出したプロファイルは等級関係を確立しないRETR_CCOMP
すべてのプロファイルを抽出し、プロファイルを二層構造(two-level hierarchy)に組織し、最上位層は連通域の周辺境界であり、二次層位内層境界RETR_TREE
全ての輪郭を抽出し網状輪郭構造を再構築輪郭検索アルゴリズム:
CHAIN_APPROX_NONE
各輪郭の各画素を取得し、隣接する2点の画素位置差が1を超えないCHAIN_APPROX_SIMPLE
水平方向、垂直方向、対角線方向の要素を圧縮し、その方向の重点座標のみを保持し、長方形の輪郭が4点で輪郭情報を保存する場合CHAIN_APPROX_TC89_L1
Teh-Chinlチェーン近似アルゴリズムCHAIN_APPROX_TC89_KCOS
Teh-Chinlチェーン近似アルゴリズム4.2輪郭の描画
cv.drawContours( , , -1 , , )
((x,y),radius) = cv.minEnclosingCircle(contour) #
実装手順:
import cv2 as cv
# 1.
def read_rgb_img(img_name):
rgb_img = cv.imread(img_name, cv.IMREAD_COLOR)
cv.imshow("rgb img", rgb_img)
return rgb_img
# 2.
def convert_rgb2gray(img):
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
return gray_img
# 3.
def convert_gray2binary(img):
# binary_img = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 5, 2)
_, binary_img = cv.threshold(img, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
return binary_img
# 4. findContours
def getContours(img):
_, contours, hierarchy = cv.findContours(img, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print(contours, hierarchy)
return contours
# 5.
def draw_contours(img, contours):
index = -1 #
thickness = 2 #
color = (255, 125, 125) #
imgg = cv.drawContours(img, contours, index, color, thickness)
cv.imshow('draw contours', imgg) #
for i, c in enumerate(contours):
circle = cv.minEnclosingCircle(c)
((x, y), radius) = circle
cv.circle(imgg, (int(x), int(y)), int(radius), (0, 0, 255), 2)
if __name__ == '__main__':
img_name = "../img/shape.jpg"
rgb_img = read_rgb_img(img_name)
gray_img = convert_rgb2gray(rgb_img)
binary_imgage = convert_gray2binary(gray_img)
contours = getContours(binary_imgage)
draw_contours(rgb_img, contours)
cv.imshow("gray_img", gray_img) #
cv.imshow("binary_img", binary_imgage) #
cv.imshow('draw_contours_circle', rgb_img) #
cv.waitKey(0)
cv.destroyAllWindows()