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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

5146閲覧

Python3で取得したH264フレームをOpenCVフレームに読み込みたい

SSaka

総合スコア96

OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/20 18:06

とあるカメラの映像をPython3で読み込みOpenCVで処理を行いたいと考えて試しています
Bufferに読んだ映像フレーム分をOpenCVのFrameに変換する方法がないかを模索しております。
知識不足で恐縮ですが、お分かりになる方がいらっしゃいましたらお願いいたします。

やりたいこと

python

1 picture = tcp_client.recv(DataLen)

上記で読み取ったpictureの変数の中身をOpenCVに1フレームとして取り込みたい

やったこと

以下のコードを含むPythonコードで取得したデータを標準出力に書き出しmplayerにリダイレクト
→ 映像を表示することができました

python

1 picture = tcp_client.recv(DataLen) 2 sys.stdout.buffer.write(picture) 3
python3 camera-receiver-mplayer.py 192.168.137.11 | mplayer -fps 10 -nosound -vc ffh264 -noidx -mc 0 -

試したこと

Python

1raw_image = picture 2image = np.frombuffer(raw_image, dtype=np.uint8) 3decoded = image 4cv2.VideoWriter_fourcc('H','2','6','4') 5cv2.namedWindow("recv",cv2.WINDOW_NORMAL) 6frame = cv2.imdecode(decoded, cv2.IMREAD_COLOR) 7cv2.imshow("recv", frame)

結果:失敗

OpenCVにフレームが渡せずサイズ認識ができていないように見える

OpenCV Error: Assertion failed (ssize.width > 0 && ssize.height > 0) in resize, file /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/imgproc/src/imgwarp.cpp, line 3492

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/10/20 22:14

"cv2.VideoWriter_fourcc"は保存する時の道具なので、表示する時には別の方法でないといけないと思います。 http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html print(type(image )) print(image.shape) の結果を教えてもらえますか? もしNumpy arrayかつ、(320,240,3)のような回答であれば、 cv2.imshow("recv", image ) cv2.waitKey(0) でそのまま表示できるはずです。
SSaka

2021/10/21 14:09 編集

コメントありがとうございます fourteenlengthさん print(type(image )) <class 'numpy.ndarray'> print(image.shape) (22660,) となっています。 jbpb0さん カメラはURLアクセス不可のため、ある一定周期でフレームのみを取得する仕様になっています。 フレーム自体はH264エンコードされています。
jbpb0

2021/10/21 14:23

> フレーム自体はH264エンコードされています。 それならやはり、デコードして生動画データにしてからOpenCVに渡すのだと思います 私が前のコメントで紹介した方法以外にも、ググったらPythonでh264のデコードができるものがいくつか見つかるので、そういうもののどれかを使って
SSaka

2021/10/26 17:52

ありがとうございます。 ありがとうございます。 HWがJetsonなので、ここでH264decodeをさせてからOpenCVに渡す方法を検討しようと 現在H264decodeをチャレンジ中です。 まだコマンドがうまく扱えて居なくチャレンジ継続しています。
guest

回答2

0

OpenCV公式によれば、GSTREAMERを使え、とあるので、

リンク先の最佳答案のようなコードが必要かもしれません。

追補

ちょっと調べるとcv2.VideoCapture(URL)というやり方もあるらしく、ソケットを使わず直でやったら動く、はあり得るかもしれません。

以下自力で勝手に思ったことです。参考にならないかもしれません。

print(image.shape)
(22660,)

これだと元の解像度が220*103というヘンテコグレースケールになるのでたぶん圧縮されていると思います。ですので、22660の一次元データを何らかの形で解像度に合致するデータに解凍しないといけなさそうです。

さらに、たぶん、ですが最低でも以下の2つが必要と思います。

  • np.frombuffernp.fromstringバッファをイメージに書き戻す
  • 元の解像度に.reshapeする必要がある

投稿2021/10/21 21:49

編集2021/10/21 21:51
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

jbpb0

2021/10/21 23:42 編集

> cv2.VideoCapture(URL)というやり方 fourteenlengthさん > カメラはURLアクセス不可 だそうです (「質問への追記・修正の依頼」より)
退会済みユーザー

退会済みユーザー

2021/10/22 21:32

補足ありがとうございます。 > カメラはURLアクセス不可 困ったちゃんなカメラですね…。ソケット通信ができるならIPアドレスはありそうなものですが… > 自前でビルド PCによりますが10-30はかかりますね。質問者さんのほかの手段がダメだった時の最後の手段的な方法かもしれません。
SSaka

2021/10/26 17:55

fourteenlengthさん、jbpb0さん ありがとうございます。 jetsonなので、ビルドされたgstreamerが使えそうなのでここにかけてチャレンジしようとしています。 IPアドレスはあるけれど直接敵にRTSPのようなものは使えないので ストリームを1個1個拾って加工が必要です
guest

0

元のデータがないので確証はありませんが、以下の方法で出来るかもしれません。

python

1picture = tcp_client.recv(DataLen) 2 3video = [] 4cap = cv2.VideoCapture(io.BytesIO(picture)) 5while(cap.isOpened()): 6 ret, frame = cap.read() 7 if ret: 8 video.append(frame) 9 else: 10 break

Python+OpenCVで動画を扱うを参考にしました。
「FFmpegがないと読み込むことができません」と注意に書かれているので気を付けてください。

投稿2021/10/21 08:51

ppaul

総合スコア24666

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

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

SSaka

2021/10/21 14:11

ありがとうございます。試してみました。 cap = cv2.VideoCapture(io.BytesIO(pitcure)) TypeError: an integer is required (got type _io.BytesIO) となりcv2.VideoCaptureで読み込めないという状況でした。 pictureにはH264フレームが1フレームずつ入っていてwhile trueで抜け出すまで 1フレームごとデータが入る形になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問