🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
OpenCV

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

Python 3.x

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

Q&A

解決済

1回答

3038閲覧

Python OPENCV Threading並行処理で参照するファイルの重複を避ける

goki_gottan

総合スコア168

OpenCV

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

Python 3.x

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

0グッド

2クリップ

投稿2021/02/09 23:28

PythonでOPENCVで画像処理をしておりますが、
ファイルが多いので高速化検討しようと考えており、並列処理したく思います。

現在は、OPENCVで画像ファイルを並列処理できておりますが、
参照している画像ファイルが時折、重複するときがあります。

そこで、以下コードのどの部分を変更したら画像ファイルの重複を避けれますでしょうか。

WIN10、PsScriter(Spyder)使用しております。

import cv2 import numpy as np import glob import os import pandas as pd import time import threading x_1,y_1,z_1,z_1_1=[],[],[],[] a,b=[],[] #保存先 r=r"◎" j1=["◎"] for j2 in j1: a.clear() t1 = time.time() dock = r"◎" for folder,subfolders,files in os.walk(dock + "\" + str(j2)): a.append('{}'.format(folder)) j=0 for d in a: global q def worker1():#-------------------------------------- global q while True: # for a in range(5): img1 = imread(r_1[q]) # 画像ファイル読み込み img1_d_1=r_1[q] q=q+1 if q>d_1-1: break img1_d_2=os.path.basename(r_1[q]) img1_d_3=img1_d_2.replace(".jpg","") x_1.append(img1_d_3) img_ch0 = cv2.split(img1)[0] w_num = cv2.countNonZero(img_ch0) y_1.append(w_num) #---------------------------------------------------- def worker2(): global q while True: if q>d_1-1: break img2 = imread(r_1[q-1]) # 画像ファイル読み込み img2_d_1=r_1[q-1] q=q+1 img2_d_2=os.path.basename(img2_d_1) img2_d_3=img2_d_2.replace(".jpg","") x_1.append(img2_d_3) img_ch0 = cv2.split(img2)[0] w_num = cv2.countNonZero(img_ch0) y_1.append(w_num) global q r_1 = glob.glob(d + "\*.jpg") j=j+1 print(j) print(d) q=0 d_1=len(r_1) t1 = threading.Thread(target=worker1) # t1 スレッドをデーモン化する t1.setDaemon(True) t2 = threading.Thread(target=worker2) x_1=[] y_1=[] t1.start() t2.start() print('started') t1.join() print("--end--") t2.join() print(set(x_1)) print(len(set(x_1))) print(y_1)

何卒、宜しくお願いいたします。

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

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

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

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

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

y_waiwai

2021/02/09 23:41

重複したらどういう不具合があるんでしょうか
goki_gottan

2021/02/09 23:52

不具合というより統計を取っておりますので、計算結果がおかしくなるのは避けたいです。 変数であるr_1は200枚程度画像が入っており、今回の評価では200で打ち切りみたいな指示を入れております。 重複は削除の指示を入れて、重複なしで200枚の時点でBreakとしてもよいのですが、他の方法で重複がなければ助かりますし、余分な画像を評価する必要がないので高速化できます。
guest

回答1

0

ベストアンサー

「並列処理、個々の処理は独立して行える」という条件の場合は concurrent.futures の ThreadPoolExecutor をおつかいください。とても簡単に並列処理が行えます。

threading を使ったやり方だとデータをチャンクに分けたり、スレッドの管理など自前で書く必要が出てきて複雑になります。

python

1import time 2from concurrent import futures 3from pathlib import Path 4 5def func(path): 6 pass # ファイルごとに行う処理を書く 7 8 9input_dir = Path("hogehoge") 10 11 12future_list = [] 13with futures.ThreadPoolExecutor() as executor: 14 for path in input_dir.glob("**/*.jpg"): # input_dir 以下にある jpg ファイル 15 # タスクを追加する。 16 future = executor.submit(func, str(path)) 17 # Future オブジェクトを記録する。 18 future_list.append(future) 19 20# 結果を受け取る 21ret = [x.result() for x in future_list]

参考:

投稿2021/02/10 01:42

tiitoi

総合スコア21956

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

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

goki_gottan

2021/02/10 02:40

ありがとうございます。スレッドごとに処理を書かなくて良い分、非常に魅力的ですが、 こちらは内部的にスレッド何個で処理していることになるのでしょうか。 スレッドの場合やマルチプロセスの場合、数を増やせば、場合によっては処理改善できます。
tiitoi

2021/02/10 02:49

ThreadPoolExecutor の引数でスレッド数を指定します。 数を増やせば、論理コア数までは速度改善が期待できます。 ``` ThreadPoolExecutor(max_workers=16) ```
goki_gottan

2021/02/10 03:02

with futures.ThreadPoolExecutor(16) as executor: このようにしたら良いのですね?試してみます。
goki_gottan

2021/02/10 04:53

非常に高速で速いです。ありがとうございます。この時点で、ベストアンサーにしたく思いますが、当初の別スレッドにしての動作を求めていた、もう一つの理由は、AスレッドとBスレッドで別処理ができる応用も考えておりました。画像の重複はありませんが、その画像らをAスレッドへ、Bスレッドへみたいにすれば、別処理ができます。たとえば、スレッドAはAフォルダへ移動、スレッドBはBスレッドへ移動なのです。 そちらの場合は、ThreadPoolExecutorでできますでしょうか。
tiitoi

2021/02/10 07:18 編集

関数の引数経由で関数に処理内容を指示すればいいのではないでしょうか。 出力先を変えるぐらいであれば、出力先のディレクトリパスを第2引数に渡せばいいと思います。 submit() の第2引数以降に関数に渡す引数をいくつでも指定できるので executor.submit(func, arg1. arg2. arg3)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問