cv2.KeyPoint を Pickling すると PicklingError が発生する 質問する

cv2.KeyPoint を Pickling すると PicklingError が発生する 質問する

特定のディレクトリ内のすべての画像でサーフィンを検索し、そのキーポイントと記述子を将来の使用のために保存したいと思います。以下に示すように、pickle を使用することにしました。

#!/usr/bin/env python
import os
import pickle
import cv2

class Frame:
  def __init__(self, filename):
    surf = cv2.SURF(500, 4, 2, True)
    self.filename = filename
    self.keypoints, self.descriptors = surf.detect(cv2.imread(filename, cv2.CV_LOAD_IMAGE_GRAYSCALE), None, False)

if __name__ == '__main__':

  Fdb = open('db.dat', 'wb')
  base_path = "img/"
  frame_base = []

  for filename in os.listdir(base_path):
    frame_base.append(Frame(base_path+filename))
    print filename

  pickle.dump(frame_base,Fdb,-1)

  Fdb.close()

実行しようとすると、次のエラーが発生します。

File "src/pickle_test.py", line 23, in <module>
    pickle.dump(frame_base,Fdb,-1)
...
pickle.PicklingError: Can't pickle <type 'cv2.KeyPoint'>: it's not the same object as cv2.KeyPoint

誰か、これは何を意味し、どのように修正すればよいか知っていますか?私はPython 2.6とOpencv 2.3.1を使用しています

大いに感謝する

ベストアンサー1

問題は、cv2.KeyPoint を pickle ファイルにダンプできないことです。私も同じ問題を抱えていましたが、基本的にキーポイントを自分でシリアル化およびデシリアル化してから Pickle でダンプすることで、この問題を回避することができました。

したがって、すべてのキーポイントとその記述子をタプルで表します。

temp = (point.pt, point.size, point.angle, point.response, point.octave, 
        point.class_id, desc)       

これらすべてのポイントを何らかのリストに追加し、Pickle でダンプします。

その後、データを再度取得したい場合は、Pickle を使用してすべてのデータをロードします。

temp_feature = cv2.KeyPoint(x=point[0][0],y=point[0][1],_size=point[1], _angle=point[2], 
                            _response=point[3], _octave=point[4], _class_id=point[5]) 
temp_descriptor = point[6]

上記のコードを使用してこのデータから cv2.KeyPoint を作成し、これらのポイントを使用して機能のリストを作成できます。

もっとすっきりした方法があると思いますが、私の場合は上記の方法で問題なく (しかも高速に) 動作します。私の特徴はフォーマット固有のリストに保存されるため、データ フォーマットを少しいじる必要があるかもしれません。私は、一般的なベースで自分のアイデアを使用して上記を提示しようとしました。これがお役に立てば幸いです。

おすすめ記事