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

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

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

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

Python 3.x

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

解決済

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

mairam
mairam

総合スコア0

OpenCV

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

Python 3.x

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

1回答

0評価

0クリップ

656閲覧

投稿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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenCV

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

Python 3.x

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