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

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

ただいまの
回答率

88.59%

None type object has no attribute 'astype'

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,616

bof

score 14

python3.6 opencv3です。
ソースコードの一部エラー箇所

descriptors = descriptors.astype(np.float32)


エラーコード

AttributeError: 'NoneType' object has no attribute 'astype'


ソースコードのエラー箇所に当たるdescriptorsは下記のコードから生成しました。

keypoints, descriptors= detector.detectAndCompute(patches[x], None)


patch[x].dtypeはuint8なのですが、descriptorsがNonetypeになってしまいます。
どのように修正すればよいのか教えていただければ幸いです。

# -*- coding: utf-8 -*-
import os
import sys
import cv2
import numpy as np
from sklearn.feature_extraction import image

## 画像データのクラスIDとパスを取得
#
# @param dir_path 検索ディレクトリ
# @return data_sets [クラスID, 画像データのパス]のリスト
def getDataSet(dir_path):
    data_sets = []    

    sub_dirs = os.listdir(dir_path)
    for classId in sub_dirs:
        sub_dir_path = dir_path + '/' + classId
        img_files = os.listdir(sub_dir_path)
        for f in img_files:
            data_sets.append([classId, sub_dir_path + '/' + f])

    return data_sets

"""
main
"""
# 定数定義
GRAYSCALE = 0
# KAZE特徴量抽出器
detector = cv2.xfeatures2d.SIFT_create()

"""
train
"""
print("train start")
# 訓練データのパスを取得
train_set = getDataSet('train_img')
# 辞書サイズ
dictionarySize = 9
# Bag Of Visual Words分類器
bowTrainer = cv2.BOWKMeansTrainer(dictionarySize)
x=0
# 各画像を分析
for i, (classId, data_path) in enumerate(train_set):
    # 進捗表示
    sys.stdout.write(".")
    # カラーで画像読み込み
    color = cv2.imread(data_path, cv2.IMREAD_COLOR)
    size = (100,100)
    colora = cv2.resize(color,size)
    patches = image.extract_patches_2d(colora, (3, 3))
    patches = patches.astype(np.uint8)
    #print(color.shape, patches.shape, patches.dtype)
    # 特徴点とその特徴を計算
    while x<9604:
        #keypoints, descriptors= detector.detectAndCompute(patches, None)
        keypoints = cv2.KeyPoint(patches[x][1][0],patches[x][0][1],size=9, angele=-1, response=0, octave=0, class_id=-1)
        descriptors = detector.compute(patches[x], keypoints)
        #print(patches[x].dtype, keypoints)
        x=x+1
    #descriptors = detector.compute(patches, keypoints)
    # intからfloat32に変換
        descriptors = descriptors.astype(np.float32)
    # 特徴ベクトルをBag Of Visual Words分類器にセット
        bowTrainer.add(descriptors)

# Bag Of Visual Words分類器で特徴ベクトルを分類
codebook = bowTrainer.cluster()
# 訓練完了
print("train finish")

"""
test
"""
print("test start")
# テストデータのパス取得
test_set = getDataSet("test_img")

# KNNを使って総当たりでマッチング
matcher = cv2.BFMatcher()

# Bag Of Visual Words抽出器
bowExtractor = cv2.BOWImgDescriptorExtractor(detector, matcher)
# トレーニング結果をセット
bowExtractor.setVocabulary(codebook)

success = 0
fail = 0

# 正しく学習できたか検証する
for i, (classId, data_path) in enumerate(test_set):
    # グレースケールで読み込み
    gray = cv2.imread(data_path, cv2.IMREAD_COLOR)
    # 特徴点と特徴ベクトルを計算
    print(gray.dtype)
    size = (100,100)
    graya = cv2.resize(gray,size)
    patches = image.extract_patches_2d(graya, (3, 3))
    print(patches.shape)
    while x<9604:
        keypoints, descriptors= detector.detectAndCompute(patches[x], None)
    # intからfloat32に変換 特徴量
        descriptors = descriptors.astype(np.float32)
    # Bag Of Visual Wordsの計算 ヒストグラム
        bowDescriptors = bowExtractor.compute(patches[x], keypoints)

    # 結果表示
    className = {"0": "airplane",
                 "1": "ferry",
                 "2": "laptop"}

    actual = "???"    
    if bowDescriptors[0][0] > bowDescriptors[0][1] and bowDescriptors[0][0] > bowDescriptors[0][2]:
        actual = className["0"]
    elif bowDescriptors[0][0] < bowDescriptors[0][1] and bowDescriptors[0][2] < bowDescriptors[0][1]:
        actual = className["1"]
    else:
        actual = className["2"]


    result = ""
    if actual == "???":
        result = " => unknown."
    elif className[classId] == actual:
        result = " => success!!"
        success = success + 1
    else:
        result = " => fail"
        fail = fail + 1

    print("expected: ", className[classId], ", actual: ", actual, result)

print("suceess percentage:", success/(success+fail))


取り込んだ画像をpatchにしたものから特徴点(keypoint)を抽出する段階で、特徴点をpatchの中心に指定したいのですが,そこがうまくいってません。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • bof

    2017/08/16 18:01

    全体のコードを載せました

    キャンセル

  • LouiS0616

    2017/08/16 18:51

    ひょっとして、網目状に特徴点を配置し、それぞれの特徴量を計算したいと言うことでしょうか?http://cdn-ak.f.st-hatena.com/images/fotolife/d/dederin-photo/20151014/20151014224351.png こんな感じに。

    キャンセル

  • bof

    2017/08/16 18:54 編集

    そうです。

    キャンセル

回答 1

checkベストアンサー

0

難しく考えすぎて、わけがわからなくなっている気がします。
sklearn.feature_extraction.image.extract_patches_2dはこの場合不要です。

また、既に特徴点を検出しているのなら、改めてdetectを行う必要はありません。
detectAndComputeより、単にcomputeを用いた方が簡潔です。


参考までに、次のようにして簡単に網目状の検出を行うことができます。
特徴点の位置は全ての画像で共通していますから、一回だけ計算して使いまわせますね。

import cv2
import numpy as np
import itertools

def detect_dense_keypoints(image_side, interval=3):
    keys = np.arange(0, image_side + 1, interval)
    keys = list(itertools.product(keys, keys))

    ret_keypoints = []
    for key in keys:
        ret_keypoints.append(cv2.KeyPoint(*key, interval))

    return ret_keypoints

def main():
    IMAGE_SIDE = 100

    src_image = cv2.imread('Lenna.png')
    src_image = cv2.resize(src_image, (IMAGE_SIDE, IMAGE_SIDE))

    keypoints = detect_dense_keypoints(image_side=IMAGE_SIDE)
    dst_image = cv2.drawKeypoints(src_image, keypoints, None)

    descriptor = cv2.xfeatures2d.SIFT_create()
    _, values = descriptor.compute(image=src_image, keypoints=keypoints)

    cv2.imshow('src', src_image)
    cv2.imshow('dst', dst_image)
    cv2.waitKey()

if __name__ == '__main__':
    main()

正直に言うと、私自身記述子がNoneになる原因は未だ突き止めていません。
しかし、特徴点の検出をもう少しスマートにすることで、見通しがつくのではないでしょうか。
直接的な回答になっておらずすみません、また上手くいかないことがあればご質問ください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/16 19:54

    ご回答ありがとうございました。特徴点の検出について修正してみたいと思います。

    キャンセル

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

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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