質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1147閲覧

Python 関数内で特定箇所のみをループしたい

mairam

総合スコア5

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/01/31 07:25

前提・実現したいこと

現在, OpenCVのハフ変換を用いた直線検出のプログラムを書いており, 検出された直線をX-means法により自動でクラスタリング, また, threshold値(直線検出の際のパラメータ)をループ処理で自動で決めて, どの画像でも一定の結果を出せるようにしたいのですが, ループ処理が上手くいかない状態です.

理想は(threshold値が大きくなるのに反比例してクラスタ数は少なくなっていくので)「threshold値を1ずつ増やしていき, X-meansにより取得したクラスタ数が2になったらループ終了」という条件で処理を行いたいのですが, 関数内での特定箇所のループの仕方が分からず困っています.(現状関数全体のループになってしまっている状態です.)

該当のソースコード

import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np from pyclustering.cluster.xmeans import xmeans, kmeans_plusplus_initializer from pyclustering.utils import draw_clusters import cv2 IMAGE_PATH = ".png" # 読み込む画像 Z = 35 def main(): image = cv2.imread(IMAGE_PATH) # 画像読み込み image2 = cv2.imread(IMAGE_PATH) # 画像読み込み gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # グレースケール化 outLineImage = cv2.Canny(gray,15, 22, apertureSize = 3) # 輪郭線抽出 cv2.imwrite("./outLine.png", outLineImage) # ファイル保存 houghList = hough_lines(image, outLineImage) # ハフ変換による直線抽出 cv2.imwrite("./result_hough.png", image) # ファイル保存 draw_cross_points(image, houghList) # 直線リストから交点を描画 cv2.imwrite("./result_hough_cross.png", image) # ファイル保存 # ハフ変換で直線を抽出する関数 def hough_lines(image, outLineImage): global Z lineList = [] lines = cv2.HoughLines(outLineImage, rho=1, theta=np.pi/50, threshold=Z) # ハフ変換で直線抽出 print("hough_lines: ", len(lines)) # print("hough_lines.shape: ", lines.shape) new_lines = np.empty((len(lines), 2)) new_lines = np.reshape(lines, (len(lines), 2)) # print("lines_3",lines) for line in lines: # print("lines_3",lines) rho, theta = line[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)) # (ρ, θ)の定義 x = (theta * 180/np.pi) y = rho # 直線グラフのプロット plt.xlim(0, 360) # x軸の表示範囲 plt.scatter(x, y, marker=".", label="hough_List") print("rho: ", rho, "theta:", x) lineList.append((x1, y1, x2, y2)) cv2.line(image,(x1,y1),(x2,y2),(0,255,0),2) # 緑色で直線を引く #X-meansによるクラスタリング # クラスタ数1から探索させてみる initial_centers = kmeans_plusplus_initializer(new_lines, 1).initialize() # クラスタリングの実行 instances = xmeans(new_lines, initial_centers, ccore=True) instances.process() # クラスタはget_clustersで取得できる np.set_printoptions(precision=2) clusters = instances.get_clusters() # クラスタの平均は以下で計算できる centers = [] lines = np.array(new_lines) # print("hough_lines.shape2: ", lines.shape) for cluster in clusters: c = lines[cluster, :] centers.append(np.mean(c, axis=0)) #クラスタ数の表示 print("Clusters: ", len(clusters)) print("Cluster", clusters) #threshold値のループ処理 while len(clusters) > 2: print("clusters in while", len(clusters)) if len(clusters) == 2: break Z += 1 print("threshold:", Z) # hough_lines(image, outLineImage) # lines = np.zeros_like(lines) # new_lines = np.zeros_like(new_lines) # Z += 1 return lineList

試したこと

thresholdループ処理のwhile文の箇所で繰り返し処理を行おうとしたのですが, ループ内部に(コメントアウトしてある部分の)hough_lines(image, outLineImage)の関数を入れた(再帰した)場合, 関数全体を(ループ箇所含めて)繰り返してしてしまっており, len(clusters)の値が変わらないためいつまでもループを続けてしまうみたいです.

lines = cv2.HoughLines(outLineImage, rho=1, theta=np.pi/50, threshold=Z) # ハフ変換で直線抽出
の部分のみをループさせたいのですが, どういった書き方にすれば上手くいくか教えていただけたら幸いです.

補足情報(FW/ツールのバージョンなど)

Python3.7, OpenCV4.1.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

do...whileでhoughLines(image, outLineImage)の関数全体を囲うことで解決しました.

投稿2020/01/31 11:04

mairam

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問