1. まず、opencv と ffmpeg の関係について説明します。
1.1 両者の関係
opencv は主に画像処理に使用されることが知られていますが、ビデオ デコード機能も含まれており、ビデオ デコード部分では ffmpeg が使用されます。どちらも画像と動画を処理できるコーデックですが、個人的にはこの 2 つは焦点が違うように感じます。
1.2 両者の違い
これが、私が上で焦点が異なると述べたことです。
OpenCV は画像の処理と画像関連の処理アプリケーションに重点を置いており、大まかに言えば PhotoShop と考えることができます。Opencv は主に、いくつかの認識および追跡マシン ビジョン アプリケーションを実行します。
FFmpeg は、ビデオとオーディオのエンコード、デコード、変換などの処理に重点を置いています。大まかに言うと、Format Factory と PotPlayer を組み合わせたものと考えることができます。主な用途はコーデック、各種フォーマット変換です。
2. Opencv と ffmpeg のバージョンが一致する
自分で環境を構築すると、バージョンの不一致による落とし穴が多すぎて怖かったので、環境を構築する前に、両者のバージョンを一致させる問題に焦点を当てました。したがって、最初にこれらの干渉要因にうまく対処しておけば、後で多くの問題を回避できます。
2.1 バージョンが一致しないとどのような問題が発生する可能性がありますか?
opencv をコンパイルすると、一部の定義が認識できないなどのさまざまなエラーが発生し、コンパイルが失敗します。
具体的には:
2.1.1 質問 1
エラー: 「CODEC_ID_H264」はこのスコープで宣言されていませんでした
{ CODEC_ID_H264, MKTAG('H', '2', '6', '4') }
ネットユーザーが提示した解決策は、コンパイル時に ffmpeg コンパイルを有効にしないことです。
-D WITH_FFMPEG=OFF
試してみたところ、コンパイルしてパスすることはできましたが、同時に腕を折ったようなもので、ffmpeg関数(ビデオ処理クラス)の使用に大きな支障をきたすか、単に使用できなくなります。したがって、バージョンを合わせて、完璧にコンパイルして、完璧に使うことが、安心して使うための基本だと思います。
2.1.2 質問 2
エラー: 「CODEC_FLAG_GLOBAL_HEADER」はこのスコープで宣言されていませんでした
この解決策は、未定義のマクロを追加することですが、根本的な原理や仕組みを深く理解していなければ、ほとんどの人は思いつかないでしょうし、この方法を理解して見つけることができるのは偉い人だけです。
つまり、基本的にはffmpegとopencvのバージョンを一致させることが問題なので、最初からちゃんとやればいいんじゃないでしょうか?
2.2 ffmpeg と opencv の一致するバージョンを確認する方法
この問題を解決するために、私は長い道のりを歩いてきましたが、最終的には数文で終わるかもしれませんが、その過程は非常に曲がりくねっていますが、その過程を通じて私はさらに深くなります。忍耐力も鍛えられ、研究心も鍛えられたし、悪くない!本題にいきましょう!
ネットユーザーが提供した方法に従って、opencv ソース コード ディレクトリに移動します。
その中に ffmpeg_version.cmake というファイルが存在するはずです。このファイルには、以下の図のように、opencv に対応する ffmpeg のバージョン番号がリストされます。
番号が付いているものは、ffmpeg の特定のバージョンの各コンポーネントに対応するバージョンであり、ffmpeg 公式 Web サイトにアクセスして、対応するバージョンのFFmpegのソースコードをダウンロードできます。
上の図は問題を説明するためのものであり、バージョン番号と具体的に一致するわけではありません。
現在の問題は、私のファイルに ffmpeg_version.cmake が存在しないことですが、当時私は混乱していました。仕方がないので、ffmpeg.cmakeを開いて手がかりがないか確認してみます。
中身を見ると、いくつかの手がかりがあり、写真にマークが付けられています。概要は次のとおりです。
1. opencv で必要な ffmpeg のバージョン番号とコミット ID 番号に対応する tag タグが表示されます。
2.ffmpeg.cmake は実際には上記の URL ***raw.git*** からダウンロードされます。
なぜ私のコンピュータにダウンロードされないのでしょうか? 一連の問い合わせの結果、Web サイトにアクセスできないことがわかり、ネットユーザーはホスト ファイルに IP を追加することも提案しました。私の解決策は、代わりに github.com を使用することですが、実際には同じです。
追加のリンクを入力します。
GitHub - opencv/opencv_3rdparty: OpenCV - サードパーティ
クリックして入力してください
opencv のコミット ID も一致していることがわかります。
それでおしまい。バージョンマッチングについてはここまでですが、全体のプロセスを理解すれば、非常に簡単になりますが、段階的に理解していないと、問題が発生したときの不安や、問題を解決した後の啓発です。
次のステップは、ffmpeg と opencv のソース コードをそれぞれダウンロードすることです。ffmpeg 公式 Web サイトのリンクが上に提供します。リリース- OpenCVは、opencv のソース コード ダウンロード リンクです。バージョンを自分で選択してください。バージョン間のバージョンが一致していることを忘れないでください。そうでない場合は、これは何のためにあるのでしょうか? それからコンパイルしてインストールし、続行しましょう。
3.ffmpegのインストール手順
インストールプロセス
opencv をインストールすると ffmpeg が使用されるため、最初に ffpmeg をインストールし、次に opencv をインストールすることをお勧めします。
まず ffmpeg ソース コードを解凍し、ソース コード ディレクトリに移動して次のコマンドを入力します。
ここでお話しますが、コマンドを入力する前に、サポート ライブラリをインストールしてください。
sudo apt-get install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev
次にパラメータ設定コマンドを入力します。
./configure --disable-x86asm --enable-shared --prefix=/usr/local/ffmpeg
パラメータの意味は、ffmpeg を /usr/local/ffmpeg ディレクトリにインストールし、完了後に入力することです。
make
中间编译的时间会有点长,依电脑的性能而定
sudo make install
すべてが完了すると、次のように /usr/local ディレクトリに ffmpeg フォルダーが表示されます。
ffmpeg のツールと動的ライブラリはすべてこの中にありますが、コンパイル中に ffmpeg の動的ライブラリを見つけるには、次の処理を行う必要があります。
创建文件ffmpeg.conf
sudo vi /etc/ld.so.conf.d/ffmpeg.conf
输入如下内容(ffmpeg动态库的路径)
/usr/local/ffmpeg/lib
最后使能生效
sudo ldconfig
インストールが成功したことを示すには、次の内容を参照してください。
ffplayg ツールを使用してビデオを再生することをテストできます。
/usr/local/ffmpeg/bin/ffplay **/**/***.mp4 (视频文件目录)
もちろん、ffmpeg の bin をグローバル変数に追加して、絶対アドレスを追加しなくてもいつでも呼び出すことができます。プロファイル ファイル (sudo vi /etc/profile) を編集して、ファイルの最後に次の行を追加します。
export FFMPEG_HOME=/usr/local/ffmpeg
export PATH=$FFMPEG_HOME/bin:$PATH
ffmpeg のインストールはここで終了です。次は opencv のインストールです。続けてください。
4. OpenCVのインストールプロセス
インストールプロセス
同様に、opencv 圧縮パッケージを解凍し、ソース コード ディレクトリに入り、pc_build フォルダーを作成します (将来クロスコンパイルを使用する場合は、遠すぎる arm_build に変更してください)。
ここでは cmake を使用してグラフィカルにコンパイルします。まず cmake ツールをインストールします。
sudo apt-get install cmake cmake-qt-gui cmake-curses-gui
次に、pc_build ディレクトリで実行します。
cmake-gui
インターフェースが表示されます
ここでは、クロスコンパイルではなく、ubuntu 環境のみを示します。
「完了」をクリックし、次に「構成」をクリックして、以下に示すようにいくつかのパラメーターを構成します。
下図の枠内にバージョン情報が表示され、ffmpegが認識されていることがわかりますが、認識されない場合はどうすればよいでしょうか?それは保留にしておいて、後で話しましょう。
最後に「生成」をクリックします。
ヒント:
cmake プロセス中にスタック状況が発生した場合は、ダウンロードする必要があるファイルが欠落しているにもかかわらず、ダウンロードできません。
例: opencv ソース コードのインストール ファイルのダウンロードの問題: ippicv_2017u3_lnx、face_landmark_model.dat、tiny-dnn
配置:打开${opencv_folder}/3rdparty/ippicv/ippicv.cmake,
第47行 "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/",
改成:"file://${path}",比如我的就是"file:///home/downloads/"
ダウンロードアドレス: https://github.com/opencv/opencv_3rdparty/tree/ippicv/
不足しているバージョンに応じてダウンロードします。ダウンロードが遅い場合は、Thunder へのリンクをコピーしてダウンロードできます。
コンパイルを開始する
コマンド インターフェイスに戻りますが、まだ急いで「make」と入力しないでください。まず、コンパイルする前に、ソース ディレクトリ内のファイル 3rdparty/protobuf/src/google/protobuf/stubs/common.cc の 33 行目に #define HAVE_PTHREAD マクロ定義を追加します。具体的な理由は、HAVE_PTHREAD マクロが pthread ライブラリを定義しているためです。
cd ..
// 返回 opencv 源码顶层目录
vi 3rdparty/protobuf/src/google/protobuf/stubs/common.cc
次に、pc_build ディレクトリに入り、次のコマンドを入力します。
make -j 16
漫长的等待编译编译完之后,安装
sudo make install
すべて成功すると、対応するファイルが /usr/local ディレクトリに生成されます。
ヘッダー ファイルと動的ライブラリが含まれます
同様に、opencvのダイナミックライブラリを見つけるには以下の処理を行います。
创建文件opencv.conf
sudo vi /etc/ld.so.conf.d/opencv.conf
输入如下内容(ffmpeg动态库的路径)
/usr/local/lib
最后使能生效
sudo ldconfig
この時点で、opencv のコンパイルとインストールは完了です。
目の前に掘られた穴
前述した落とし穴の 1 つは、cmake の実行時に ffmpeg のバージョンが表示されない場合の対処方法です。私のアプローチは、最初にコンパイルしてそれを無視することです。コンパイルが完了したら、ffmpeg の pkgconfig 内のすべての PC ファイルを /usr/local/ にコピーします。 lib/ pkgconfig では、このファイルには opencv の pc ファイルが含まれます。
sudo cp /usr/local/ffmpeg/lib/pkgconfig/*.pc /usr/local/lib/pkgconfig
その後、上記の操作に従って opencv を再コンパイルすると、少しクラッシュしますか? それはありません。
もちろん、私もいくつかの操作を考えましたが、一部のネットユーザーは、ffmpeg をインストールした後、次の操作を行ってから、opencv をコンパイルすると言いました。
sudo vi /etc/profile
添加
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig
让环境变量生效
source /etc/profile
このように処理しましたが、役に立たないようです。何が起こったのかわかりません。ネットユーザーがこのことを知っている場合は、メッセージを残して知らせてください。
ffmpeg と opencv がインストールされたので、興奮を抑えることができず、ぜひ試してみたいと思っています。次に、小さな栗をいくつか取って、ナイフを研ぎます、ははは。
5. 実際の操作
ラバか馬が出てきて走り回ります。これまで操作の学習と練習のためにたくさんのことを行いました。次に、その機能を実行するための小さなプログラムをいくつか書きます。
5.1 画像を表示する
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv)
{
Mat image = imread("11.png", 1 );//加载
cv::namedWindow("picture",CV_WINDOW_AUTOSIZE);
cv::imshow("picture", image);//显示图片
waitKey(5000);//等待
return 0;
}
5.2 ビデオを再生する
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
//从摄像头读取视频
VideoCapture capture("video.mp4");
//循环显示每一帧
while (1)
{
Mat frame;//定义一个Mat变量,用于存储每一帧的图像
capture >> frame;//读取当前帧
imshow("读取视频帧", frame);//显示当前帧
waitKey(30);//延时30ms
}
system("pause");
return 0;
}
5.3 ラップトップの内蔵カメラを使用してビデオを撮影し、保存する
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv)
{
//打开电脑摄像头
VideoCapture capture(0);
if(!capture.isOpened()){
cout<<"error"<<endl;
waitKey(0);
return 0;
}
//获得分辨率
int w = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT));
cout<<"w="<<w<<endl;
cout<<"h="<<h<<endl;
Size videoSize(w,h);
VideoWriter writer;
writer.open("video.mp4",CV_FOURCC('M','J','P','G'),25,videoSize);
if(!writer.isOpened()){
cout<<"fail"<<endl;
return -1;
}
Mat frame;
int key;
char startorstop=1;
char flag=0;
while(1){
capture >> frame;
if(key == 32){//按下空格开始录制、暂停录制 可以来回切换
startorstop = 1-startorstop;
if(startorstop == 0){
flag = 1;
}
}
if(key == 27){//按下ESC退出整个程序,保存视频文件到磁盘
cout << "exit" << endl;
break;
}
if(startorstop == 0 && flag == 1){
writer << frame;
cout << "recording" << endl;
}else if(startorstop == 1){
flag = 0;
cout << "end recording" << endl;
}
imshow("picture",frame);
key=waitKey(100);
cout<<"key="<<key<<endl;
}
capture.release();
writer.release();
destroyAllWindows();
return 0;
}
コンパイルスクリプト
g++ test.cpp -o test -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs
はい、これで終わりです。途中で踏まなければいけないと思う穴はほとんど踏みました。簡単ではありません。あなたの創造性を自由に発揮して、これから先の道を進んでください。
間違いがある場合は、修正してください。