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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

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

Q&A

解決済

1回答

3364閲覧

画像分割をして特徴分析したいがヒストグラムに渡せない?

Mr_K

総合スコア28

Python 3.x

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

0グッド

0クリップ

投稿2019/05/31 06:43

編集2019/05/31 08:25

画像を分割して,色ヒストグラムを算出するプログラムを作りたいのですが以下のエラーが行き詰っています.
どなたかご教授ください

前回,質問した時にヒストグラムに渡せていなかったので追加しました.が以下のようにエラーが出てしまいまいました.
何も返せていないということなのですが,どこで誤っているのかわかりません.
やりたいことは分割してそれぞれで算出したHSVをヒストグラムにしたいです.

(264, 352, 3) -> (264, 351, 3) Traceback (most recent call last): File "image_descriptor.py", line 46, in <module> x = range(len(features)) TypeError: object of type 'NoneType' has no len()

python

1#_*_ coding: utf-8 _*_ 2import cv2 3import matplotlib.pyplot as plt 4import numpy as np 5 6 7class ImageDescriptor: 8 def __init__(self,histSize): 9 self.histSize = histSize #クラスの変数に登録 10 """ 11 画像を3x3に分割し、各ブロックで算出されたHSV色ヒストグラムを結合して返す関数. 12 filename : 画像のファイルパス 13 """ 14 def describe(self,filename): 15 features = [] 16 num_vsplits = 3 17 num_hsplits = 3 18 19 img = cv2.imread(filename) 20 img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)#RGB空間からHSV空間に変換 21 channels = [0,1,2] 22 mask = None #画像マスクを使用しない 23 #histSize =[10,4,4] 24 ranges = [0,180,0,256,0,256] 25 26 h,w = img.shape[0:2] 27 crop_img = img[:h // num_vsplits * num_vsplits, :w// num_hsplits * num_hsplits] 28 print('{} -> {}'.format(img.shape,crop_img.shape)) 29 30 for h_img in np.vsplit(crop_img, num_vsplits): 31 #垂直方向に分割する 32 for v_img in np.hsplit(h_img, num_hsplits): 33 features.append(v_img) 34 hist = cv2.calcHist([v_img],channels,mask,histSize,ranges) 35 hist_vec = hist.flatten() 36 n_hist_vec = hist_vec / hist_vec.sum() 37 features = features.extend(n_hist_vec) 38 return features 39 40if __name__ == '__main__': 41 histSize =[10,4,4] 42 img_dsc = ImageDescriptor(histSize) 43 filename = './holidays/database/10.jpg' 44 features = img_dsc.describe(filename) 45 print(type(features)) 46 x = range(len(features)) 47 plt.bar(x,features) 48 plt.show()

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

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

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

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

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

tiitoi

2019/05/31 07:20 編集

describe() で9枚の画像に分割され、features は (9, 140, 186, 3) の配列になっていると思うのですが、これをどうしたいのでしょうか?
tiitoi

2019/05/31 07:59

> 質問の編集をうけて 分割後の各画像に対して、それぞれRGB のヒストグラムを計算して、プロットしたいということでしょうか? (9個のヒストグラムを表示するイメージ?)
Mr_K

2019/05/31 08:26

分割してそれぞれで算出した色ヒストグラムを結合したいです.
tiitoi

2019/05/31 09:08

カラー画像1つのヒストグラムは (3, 256) の配列で得られると思いますが、分割した9個の領域のそれぞれのヒストグラムを (9, 3, 256) の配列で得られればよいということですか?
guest

回答1

0

ベストアンサー

やりたいことを以下と解釈して、そのコードを記載しました。

  1. 画像を分割する。
  2. 分割した各領域の HSV ヒストグラムを作成する。

意図と違った場合はコメントしてください。

サンプルコード

python

1import cv2 2import matplotlib.pyplot as plt 3import numpy as np 4 5 6def split_imgs(img, hsplits=3, vsplits=3): 7 h, w = img.shape[:2] 8 crop_img = img[: h // vsplits * vsplits, : w // hsplits * hsplits] 9 10 return np.array( 11 [x for h_img in np.vsplit(crop_img, vsplits) for x in np.hsplit(h_img, hsplits)] 12 ) 13 14 15def hsv_hist(img): 16 # HSV 色空間に変換する。 17 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 18 19 # 各チャンネルのヒストグラムを計算する。 20 hists = [] 21 for ch in range(3): 22 hist = cv2.calcHist([hsv], [ch], None, histSize=[256], ranges=[0, 256]) 23 hists.append(hist) 24 return hists 25 26 27# 画像を読み込む。 28hsplits = 3 # 横方向の分割数 29vsplits = 3 # 縦方向の分割数 30img = cv2.imread("test.jpg") 31 32# 画像を分割する。 33sub_imgs = split_imgs(img, hsplits, vsplits) 34print(sub_imgs.shape) # (9, 140, 186, 3) 35 36# 各画像のヒストグラムを取得する。 37hists = np.array([hsv_hist(x) for x in sub_imgs]) 38print(hists.shape) # (9, 3, 256, 1) 39 40# ヒストグラムを描画する。 41ch_names = {0: "H", 1: "S", 2: "V"} 42 43fig, axes = plt.subplots(hsplits, vsplits, figsize=(10, 10)) 44for ax, hsv_hist in zip(axes.ravel(), hists): 45 # 各ヒストグラムを描画する。 46 for hist, [ch] in zip(hsv_hist, channels): 47 ax.plot(hist, label=ch_names[ch]) 48 ax.set_xlim([0, 256]) 49 ax.set_xlabel("Pixel Value") 50 ax.legend() 51plt.show()

イメージ説明

内容の解説

  • cv2.calcHist() の使い方

OpenCV - calcHist() で画像のヒストグラムを作成する

  • 画像の分割

OpenCV - 画像をグリッド上に分割する方法について

  • cvtColor の変換の注意点

cvtColor で HSV 色空間に変換した際に各チャンネルの範囲は利便性のため、[0, 255] にスケールされます。
なので、ヒストグラムを計算する際は HSV ともに histSize=[256], ranges=[0, 256] でよいです。

OpenCV: Color Space Conversions

投稿2019/05/31 09:52

tiitoi

総合スコア21956

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

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

Mr_K

2019/06/02 13:03

この方法を参考にします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問