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

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

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

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

Python 3.x

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

Q&A

1回答

2817閲覧

抽出画像以外(背景)のぼかし方

kkkkkkkaaaa

総合スコア0

OpenCV

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

Python 3.x

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

0グッド

0クリップ

投稿2021/01/15 06:19

前提・実現したいこと

初心者です。
pythonを用いてポートレート(被写体を検出してそれ以外の背景をぼかす)を実装したいと考えています。

発生している問題・エラーメッセージ

現在、被写体の抽出までは完成しています。その後、抽出した範囲以外をぼかす作業に苦戦しています。
どうすれば被写体以外をぼかすことができるでしょうか。教えていただけると嬉しいです。

該当のソースコード

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('dog.jpg') #任意の画像

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

lower_white = np.array([0,0,100])
upper_white = np.array([180,80,255])

mask_white = cv2.inRange(hsv, lower_white, upper_white) #指定した範囲の画素を255、それ以外の画素を0として2値化を行う
cv2.imwrite("sirokuro.jpg", mask_white)

contours, hierarchy = cv2.findContours(mask_white, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #輪郭の取得

target_contour = max(contours, key=lambda x: cv2.contourArea(x)) #一番大きい輪郭抽出

for i in target_contour:
x,y = i.ravel()
cv2.circle(img, (x,y), 3, 255, -1)

plt.imshow(img), plt.show()

roi = (111, 127, 631, 645) #処理領域を設定

dst_img = img.copy()

s_roi = img[roi[1]:roi[3], roi[0]:roi[2]] #ROI領域を抜き出す

s_roi = cv2.blur(s_roi, (30, 30)) #抜き出した画像をぼかす

dst_img[roi[1]:roi[3], roi[0]:roi[2]] = s_roi #出力画像の同じ箇所に埋め込み

plt.imshow(dst_img), plt.show()

試したこと

上記のソースコードを実行した際の結果を添付します。

イメージ説明

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

python 3.7.9
opencv 4.5.1

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

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

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

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

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

tiitoi

2021/01/15 07:21 編集

ソースコードはインデントが崩れてしまうため、マークダウン記法で記載してください。あと変換前の画像を添付していただけますか?
guest

回答1

0

  • 「被写体」領域内の画素はぼかさない
  • ぼかし結果を求める際に「被写体」領域内の画素を用いないようにする

とすれば良いのではないでしょうか.

投稿2021/01/15 08:46

fana

総合スコア11658

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

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

fana

2021/01/15 08:52

CVのblur() とかには,参照する画素を制限するような指定はできなそうだから,カーネル範囲が「被写体」領域にかかる範囲については自前でぼかし計算するしかないかも.
fana

2021/01/15 09:02 編集

ボックスフィルタで良ければ, (1)【元画像に対して「被写体」領域内の画素値を真っ黒(0,0,0)にした画像】から計算した Integral Image (2)【「被写体」領域内の画素値を0, 他の場所の画素値を1 としたマスク画像】から計算した Integral Image の2つを用意すれば,この2つからぼかし結果を得られるように思う. (1)側から求めた,ある画素位置を中心とするフィルタカーネル範囲内の画素値の合計 は,元画像の「被写体」範囲内の画素値を除いた合計 となる. (2)側からは,同範囲内に関する【「被写体」範囲内ではない画素の個数】を得られるから,それを分母にして平均値を求めればよい.
kkkkkkkaaaa

2021/01/16 12:40

ご回答ありがとうございます。 頑張ってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問