序文:前回のJetson Nanoの記事では、学習のためのアイデアや教材を紹介しました。今日は、引き続きJetson NanoでOpenCVを使用する方法についての記事をシェアします。 OpenCV の正式名称は Open Source Computer Vision Library で、クロスプラットフォームのコンピューター ビジョン ライブラリです。 OpenCV は Intel Corporation によって開始され、共同開発され、BSD ライセンスの下でリリースされました。商用および研究分野で無料で使用できます。 OpenCV は、リアルタイム画像処理、コンピューター ビジョン、パターン認識プログラムの開発に使用できます。 視覚処理では、OpenCV の使用が基本的な部分であるため、ボードを使用する過程では、OPECV の使用が最初のハードルとなります。次に、Jetson Nano で OpenCV の Python バージョンと C++ バージョンを使用する手順を紹介します。C++ の使用部分では、それぞれ CMake と Makefile コンパイルの 2 つの方法を紹介します。 oepcv はじめに: OpenCV の目標は、コンピューター ビジョンの問題を解決するためのツールを提供することです。場合によっては、ライブラリ内の高レベル関数によってコンピューター ビジョンの問題を効果的に解決できます。一度に解決できない問題に遭遇した場合でも、ライブラリ内の基本コンポーネントは、あらゆるコンピューター ビジョンの問題に対処するソリューションのパフォーマンスを強化するのに十分なほど充実しています。 基本機能: OpenCV の応用分野は非常に広く、画像ステッチ、画像ノイズ除去、製品品質検査、ヒューマン コンピュータ インタラクション、顔認識、動作認識、動作追跡、無人運転などが含まれます。また、機械学習モジュールも提供しており、通常のベイズ、K 近傍法、サポート ベクター マシン、決定木、ランダム フォレスト、人工ニューラル ネットワークなどの機械学習アルゴリズムを使用できます。 注: サンプル コードは他のブロガーの記事を参照しています。 Opencv-python の使用方法: Opencv-python は比較的簡単に使用できます。cv2 をインポートすると、opencv-python モジュールの機能を使用して必要なアクションを実行できます。以下では、比較的簡単な画像変換デモを紹介します。 opencv-python のインストール pip3 インストール opencv - python サンプルコード: 「」 「 」 カラー画像をグレースケールに変換する 「 」
#import はモジュールをインポートします。モジュール内の関数を使用するたびに、それがどのモジュールであるかを指定する必要があります。 #from…import *モジュールをインポートします。モジュール内の関数を使用するたびに、関数を直接使用します。関数がどのモジュールに属しているかは既にわかっていることに注意してください。 from skimage.color import rgb2gray #skimage グラフィックス処理ライブラリ color は色空間変換サブモジュールです pip install scikit - image numpyをnp としてインポートする import matplotlib .pyplot as plt #matlab の python ライブラリ pip install matplotlib from PIL import Image # Python Imaging Library 画像処理ライブラリ pip install pillow cv2をインポート
# 画像をグレースケール化する
#cv2 メソッド 画像= cv2.imread ( "/home/lyn/Pictures/318c944a7daa47eaa37eaaf8354fe52f.jpeg" ) h , w = img .shape [ : 2 ] #画像の高さと幅を取得します img_gray = np .zeros ( [ h , w ] , img .dtype ) #現在の画像と同じサイズのシングルチャンネル画像を作成します i が範囲( h ) 内にある場合: jが範囲( w ) 内にある場合: m =画像[ i , j ] img_gray [ i , j ] = int ( m [ 0 ] * 0.11 + m [ 1 ] * 0.59 + m [ 2 ] * 0.3 ) #BGR座標をグレー座標に変換 印刷( img_gray ) print ( "画像表示グラフ: %s" % img_gray ) cv2.imshow ( "imageshow gray" 、 img_gray )
#plt メソッド plt .subplot ( 221 ) # は、画像ウィンドウ全体を 2 行 2 列に分割することを意味し、現在の位置は 1 です。 img = plt .imread ( "/home/lyn/Pictures/318c944a7daa47eaa37eaaf8354fe52f.jpeg" ) plt .imshow (画像) print ( "----image lenna -----" ) 印刷(画像)
#グレースケール img_gray = rgb2gray (画像) plt .subplot ( 222 ) plt .imshow ( img_gray 、 cmap = "gray" ) print ( "-----画像グレー-------" ) 印刷( img_gray )
# 二値化 img_binary = np .where ( img_gray >= 0.5 , 1 , 0 ) 印刷( "-----imge_binary------" ) 印刷( img_binary ) 印刷( img_binary .shape )
#plt メソッド plt .subplot ( 223 ) plt .imshow ( img_binary 、 cmap = 'gray' ) plt .show ( ) 関数 Opencv c++ の使用法: opencv-c++ をインストールするには、一般的なシステムでは、公式 Web サイト https://opencv.org にアクセスし、対応するパッケージをダウンロードしてから、コンパイルされた opencv ファイルが指定されたディレクトリにインストールされるまで、camke->make->make install を実行する必要があります。 ただし、Jetson Nano イメージ パッケージには opencv4 がプリインストールされており、バージョンは 4.1 以降です。コマンドを使用してクエリを実行したところ、インストールしたイメージのOpenCVバージョンは4.1.1でした。 jetson@jetson -デスクトップ: / usr / include / opencv4 / opencv2$opencv_version 4.1 .1 C++ で Opencv を開発するには、追加の設定が必要です。まず、opencv ヘッダー ファイルの場所を確認します。 Jetson では、OpenCV のヘッダー ファイルは /usr/include/opencv4/ というディレクトリにあります。このディレクトリは、後でコンパイル リンク ファイルに書き込まれます。 リンクファイルの場所: ls libopencv* 具体的なパスは /usr/lib/aarch64-linux-gnu で、このディレクトリは後でコンパイル リンク ファイルに書き込まれます。 C++ 開発では、通常、パッケージ化とコンパイルに make ツールまたは cmake ツールを使用します。ここでは、opencv を呼び出すための 2 つの C++ ライブラリ、makefle と cmake も紹介します。 メイクファイルMakefile ファイル共有では、LIBS によってリンクされる opencv の特定のファイルを 1 つずつ書き込む必要があることに注意してください。ここではよく使われるパッケージをいくつか書きましたので、必要に応じて追加できます。 OBJS = * .o CFLAGS = -Wall -g -std = c ++ 11 CC = gcc CPP = g ++ INCLUDES +=- I / usr / include / opencv4 / - I / usr / local / include # コンパイルヘッダーファイルディレクトリ LIBS += -L / usr / lib / aarch64 - linux - gnu-lopencv_core - lopencv_imgcodecs - lopencv_imgproc - lopencv_highgui - lopencv_objdetect #使用されている特定のライブラリへのリンク
ターゲット: $ { OBJS } # g ++ -oターゲットboost_thread.o - llua - ldl @echo "-- start " $ { CC } $ { CFLAGS } $ { OBJS } -o $@ $ { INCLUDES } $ { LIBS } $ ( CPP ) $ { CFLAGS } $ { OBJS } -o $@ $ { INCLUDES } $ { LIBS }
クリーン: -rm -f * .o core * .coreターゲット
% .o : % .cpp #srcディレクトリ内のすべての.cppファイルを.oファイルにコンパイルします $ { CPP } $ { CFLAGS } $ { INCLUDES } -c $ < コード show_img.cpp: #include < opencv2 / opencv .hpp > #include < iostream > 名前空間 std を使用します。 名前空間 cv を使用します。
int main ( int argc 、 char ** argv ) の { std :: cout << "hello opencv" << std :: endl ;
//グレースケール画像表示 Mat src = imread ( "/home/jetson/lyn_work/c++/sp_noise.png" , IMREAD_GRAYSCALE ) ; //読み込まれるデータはマトリックスの形式です。2番目のパラメータはグレースケール画像の表示を表します。 if ( src .empty ( ) )の場合 { std :: cout << "画像を読み込めませんでした" << endl ; //画像が存在しない場合は、読み取って端末に印刷することはできません。 } //画像が画面サイズを超えて表示できない場合にこの関数を呼び出します。 namedWindow ( "入力ウィンドウ" , WINDOW_GUI_EXPANDED ) ; //新しいウィンドウを作成します。パラメータ 1 は名前を表し、2 番目のパラメータは空き比率を表します。 imshow ( "入力ウィンドウ" , src ) ; //新しく作成された入力ウィンドウに表示されていることを示します。最初のパラメータはウィンドウ名を示し、src はデータオブジェクト Mat を示します。 waitKey ( 0 ) ; //この文を実行すると、プログラムはブロックされます。パラメータは遅延時間を示します。単位: ミリ秒 destroyAllWindows ( ) ; //以前に作成した表示ウィンドウを破棄する 0を返します。 } コンパイルして実行します: 作る 。/ターゲット ここに画像の説明を挿入 メイクCMakeLists.txt ファイルの内容に対応: cmake コンパイルでは、使用するリンクは OpenCV 動的ライブラリ ファイルに対応しているため、Makefile ファイルのように 1 つずつ追加する必要はありません。cmake はすべての opencv リンク ファイルを追加するのと同じなので、非常に便利です。そこで、後で cmake クラスに追加の例を書きました。 cmake_minimum_required (バージョン2.8 )
#cmakeプロジェクトを宣言する プロジェクト( opencv_learn )
# コンパイルモードを設定する #set ( CMAKE_BUILD_TYPE "デバッグ" )
#OPENCVライブラリを追加 #OpenCVのバージョンを指定します。コードは次のようになります #find_package ( OpenCV 4.2が必要) #OpenCVのバージョンを指定する必要がない場合、コードは次のようになります find_package ( OpenCV 必須)
ディレクトリを含める( ./src/ )
#OpenCV ヘッダーファイルを追加 include_directories ( $ { OpenCV_INCLUDE_DIRS } ) は、
#OpenCV_INCLUDE_DIRSの値を表示する メッセージ( $ { OpenCV_INCLUDE_DIRS } )
ファイル( GLOB_RECURSE TEST_SRC #ソース
cmake コンパイルを実行します: mkdir ビルド .. のcmakeを実行します。 作る demo1: make の例と同じ show_img.cpp コード ファイルを使用します。上記の内容を参照してください。 。/ターゲット demo2: C++ を使用して CSI カメラを読み取ります。ビデオ ストリーム イメージは正常に表示できますが、vnc 接続のため色が少し歪んでいることがわかります。CMakeLists.txt に次の 2 行を追加します。 add_executable ( open_csi open_csi .cpp $ { TEST_SRC } )
ターゲットリンクライブラリ( open_csi$ { OpenCV_LIBS } ) open_csi.cpp コード ファイルは次のとおりです。 #include < iostream > #include <文字列> #include < opencv4 / opencv2 / opencv .hpp > #include < opencv4 / opencv2 / core .hpp > #include < opencv4 / opencv2 / highgui .hpp > #include < opencv4 / opencv2 / imgproc .hpp > #include < opencv4 / opencv2 / objdetect.hpp > #include < opencv4 / opencv2 / imgproc / types_c.h > #include < opencv4 / opencv2 / videoio .hpp >
名前空間 std を使用します。 名前空間 cv を使用します。
文字列 gstreamer_pipeline ( intキャプチャ幅、 intキャプチャ高さ、 intディスプレイ幅、 intディスプレイ高さ、 intフレームレート、 int反転方法) { "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)" + to_string ( capture_width ) + ", height=(int)"を返します+ to_string (キャプチャー高さ) + ", format=(文字列)NV12, framerate=(小数点)" + to_string (フレームレート) + "/1 ! nvvidconv flip-method=" + to_string ( flip_method ) + " ! video/x-raw, width=(int)" + to_string ( display_width ) + ", height=(int)" + to_string ( display_height ) + ", format=(文字列)BGRx ! videoconvert ! video/x-raw, format=(文字列)BGR ! appsink" ; }
int main ( int argc 、 char ** argv ) の { キャプチャ幅= 1280 ; キャプチャ高さ= 720 ; ディスプレイの幅= 1280 ; ディスプレイの高さを720 にする フレームレート= 60 ; int flip_method = 0 ;
//パイプラインを作成する 文字列パイプライン= gstreamer_pipeline (キャプチャ幅, キャプチャ高さ、 表示幅、 ディスプレイの高さ、 フレームレート、 反転メソッド) ; std :: cout << "gstreamer パイプラインを使用しています: \n\t" << pipeline << "\n" ;
//パイプラインをビデオストリームにバインドする ビデオキャプチャキャップ(パイプライン、 CAP_GSTREAMER ) ; if ( ! cap .isOpened ( ) ) { std :: cout << "カメラを開けませんでした。" << std :: endl ; ( -1 ) を返します。 }
//表示ウィンドウを作成する namedWindow ( "CSI カメラ" 、 WINDOW_AUTOSIZE ) ; マット画像;
//フレームごとに表示 ( 真)の間 { if ( ! cap .read ( img ) ) { std :: cout << "キャプチャに失敗しました" << std :: endl ; 壊す; } int new_width 、 new_height 、幅、高さ、チャンネル; 幅= img .cols ; 高さ= img .rows ; チャンネル= img .channels ( ) ;
//画像サイズを調整する 新しい幅= 640 ; (幅> 800 )の場合 { new_height = int ( new_width * 1.0 /幅*高さ) ; } resize ( img , img , cv :: Size ( new_width , new_height ) ) ;
imshow ( "CSIカメラ" 、 img ) ;
int keycode = cv :: waitKey ( 30 ) & 0xff ; // ESCキーで終了 if (キーコード== 27 ) break ; }
キャップ.release ( ) ; すべてのウィンドウを破棄します( ) ; }
表示効果はスクリーンショットのとおりです。 結論これは、Jetson Nano で OpenCV を使用する基本についての私の共有です。後で、顔認識、オブジェクト認識、ジェスチャ認識など、OpenCV に基づくさらに興味深いプロジェクトをいくつか実行できます。より良いアイデアやニーズがある場合は、ぜひ私を友達として追加して、コミュニケーションや共有を行ってください。 著者: 良心は依然として存在し、昼間は懸命に働き、夜は公開アカウントの原作者です。公式アカウントの内容には、テクノロジー以外にも、人生に関する洞察も盛り込まれています。真剣にコンテンツをアウトプットする職場のベテランであると同時に、写真、音楽、バスケットボールなど、テクノロジーの枠を超えて人生を豊かにする人でもあります。私について来て、私と一緒に歩いてください。
|