ラズパイ3bの環境
- OS Raspbian64bit
- ラズパイ用カメラモジュール
- コンパイラ gcc(Mingw)
- OpenCV 3.4.1(Mingw用にビルド済み)
<実行したいこと>
ラズパイ3bで顔認証を行いたいのですが、Mingwで既にビルドされたソースコードhttps://github.com/huihut/OpenCV-MinGW-Build/tree/OpenCV-3.4.1を使います。
ダウンロードしてみたところライブラリはなかったのですが、ラズパイのCPU(ARM)用にビルド前のソースコードをコンパイルしてラズパイのCPU用にライブラリを作れということでしょうか?
こちらがソースコードです。
#include "cv.h" #include "highgui.h" #define CONTROL_LED #ifdef CONTROL_LED #include <bcm2835.h> #endif // 未来カメラのメインプログラム int calcBrightness(CvRect* rect,IplImage* frame); int main() { int key; char str[32]; int brightness; #ifdef CONTROL_LED // BCM2835ライブラリの初期化 if(!bcm2835_init()){ printf("bcm2835_init failed\n"); return(-1); } // P1端子11番ピンを出力、LOW設定にする bcm2835_gpio_fsel(RPI_V2_GPIO_P1_11,BCM2835_GPIO_FSEL_OUTP); bcm2835_gpio_write(RPI_V2_GPIO_P1_11,LOW); #endif CvCapture *capture = 0; IplImage *frame = 0; CvHaarClassifierCascade* cvHCC = (CvHaarClassifierCascade*)cvLoad("/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml"); CvMemStorage* cvMStr = cvCreateMemStorage(0); CvSeq* face; CvFont font; // ウィンドウの作成とフルスクリーン表示設定 cvNamedWindow ("capture_window", 0); cvSetWindowProperty("capture_window",CV_WND_PROP_FULLSCREEN,CV_WINDOW_FULLSCREEN); // フォント構造体の初期化 cvInitFont(&font,CV_FONT_HERSHEY_PLAIN,1,1); // カメラからのビデオキャプチャを初期化 capture = cvCreateCameraCapture (0); // 取得するカメラ画像の幅と高さを設定(カメラにより指定できる値が異なります) cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, (double)160); cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, (double)120); while (1) { // 1フレーム取り出す frame = cvQueryFrame (capture); // 画像中から検出対象の情報を取得 face = cvHaarDetectObjects(frame, cvHCC, cvMStr); #ifdef CONTROL_LED // 顔検出数がゼロならLED消灯、それ以外なら点灯の為にGPIOを制御する if(face->total == 0){ bcm2835_gpio_write(RPI_V2_GPIO_P1_11,LOW); } else { bcm2835_gpio_write(RPI_V2_GPIO_P1_11,HIGH); } #endif // 検出した個数分のループを回す for (int i = 0; i < face->total; i++) { CvRect* faceRect = (CvRect*)cvGetSeqElem(face, i); // 顔検出領域の輝度を取得 brightness = calcBrightness(faceRect,frame); sprintf(str,"B:%d",brightness); // 顔の位置に矩形、その下に輝度情報をテキスト表示する cvRectangle(frame, cvPoint(faceRect->x, faceRect->y), cvPoint(faceRect->x + faceRect->width, faceRect->y + faceRect->height), CV_RGB(255, 255 ,0), 2, CV_AA); cvPutText(frame,str,cvPoint(faceRect->x, faceRect->y + faceRect->height + 16), &font,CV_RGB(255,255,0)); } cvShowImage ("capture_window", frame); key = cvWaitKey (1); if (key == ' ') { break; } // ダミーでフレームを取得(遅延量を少なく出来るように調整) cvQueryFrame (capture); cvQueryFrame (capture); cvQueryFrame (capture); cvQueryFrame (capture); } cvReleaseMemStorage(&cvMStr); cvReleaseCapture (&capture); cvDestroyWindow("capture_window"); cvReleaseHaarClassifierCascade(&cvHCC); return 0; } // 指定した領域の輝度平均値を得る int calcBrightness(CvRect* rect,IplImage* frame) { int x; int y; unsigned char r,g,b,mono; unsigned long sum; sum = 0; // rectで指定された領域サイズでループを回す for(y=rect->y;y<(rect->y+rect->height);y++){ for(x=rect->x;x<(rect->x+rect->width);x++){ b = frame->imageData[frame->widthStep*y+x*3 ]; g = frame->imageData[frame->widthStep*y+x*3+1]; r = frame->imageData[frame->widthStep*y+x*3+2]; // モノクロのデータを算出 mono = (unsigned char)((float)r*0.30f + (float)g*0.59f + (float)b*0.11f); sum += mono; } } // 平均値を戻す return(sum / (rect->width*rect->height)); }
<疑問に思ったこと>
ラズパイでopencvのライブラリが得られたとして、なぜそのライブラリが正常に動くのでしょうか?
ビルドされる前のライブラリのソースコードがどのような出力をするかわからないと思います。その出力されたバイナリデータ(ライブラリ)がラズパイでコンパイルしただけで正常に動く実行ファイルが得られる理由がわかりません。
ラズパイの設計者がgccでopencvのライブラリを使う事を考慮して設計したため実行ファイルが正常に動くのでしょうか?
<編集>
今更ですが、この本を参考にしてラズパイでOpencvを使おうと考えていました。
http://www.kumikomi.net/interface/contents/201401.php
載せたソースコードはこの本のサポートページに載っていたものです。
どうやら#include <bcm2835.h>が関係しているようです。
ただ、このbcm2835がARMやライブラリにどのように働くかは中身を見てみないとわからないので調べてみます。
<編集2>
PCの方でもビルドしてみました。
PCの環境
- Windows10 64bit
- OPENCV3.2.0
- VS2107
実行ファイルが得られたのですが、実行すると停止してしまいます。
必要なDLLはそろえたのですが実行は出来ませんでした。
ラズパイでないので少しプログラムを編集しました。
こちらがプログラムです。
プログラム自体はラズパイでビルドする予定のものなのでうまくいかなかったのかもしれません。
(ほかに原因があるように思えますが。)
#include <opencv/cv.h> #include <opencv/highgui.h> // 未来カメラのメインプログラム int calcBrightness(CvRect* rect, IplImage* frame); int main() { int key; char str[32]; int brightness; CvCapture *capture = 0; IplImage *frame = 0; CvHaarClassifierCascade* cvHCC = (CvHaarClassifierCascade*)cvLoad("/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml"); CvMemStorage* cvMStr = cvCreateMemStorage(0); CvSeq* face; CvFont font; // ウィンドウの作成とフルスクリーン表示設定 cvNamedWindow("capture_window", 0); cvSetWindowProperty("capture_window", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); // フォント構造体の初期化 cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1, 1); // カメラからのビデオキャプチャを初期化 capture = cvCreateCameraCapture(0); // 取得するカメラ画像の幅と高さを設定(カメラにより指定できる値が異なります) cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, (double)160); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, (double)120); while (1) { // 1フレーム取り出す frame = cvQueryFrame(capture); // 画像中から検出対象の情報を取得 face = cvHaarDetectObjects(frame, cvHCC, cvMStr); // 検出した個数分のループを回す for (int i = 0; i < face->total; i++) { CvRect* faceRect = (CvRect*)cvGetSeqElem(face, i); // 顔検出領域の輝度を取得 brightness = calcBrightness(faceRect, frame); sprintf(str, "B:%d", brightness); // 顔の位置に矩形、その下に輝度情報をテキスト表示する cvRectangle(frame, cvPoint(faceRect->x, faceRect->y), cvPoint(faceRect->x + faceRect->width, faceRect->y + faceRect->height), CV_RGB(255, 255, 0), 2, CV_AA); cvPutText(frame, str, cvPoint(faceRect->x, faceRect->y + faceRect->height + 16), &font, CV_RGB(255, 255, 0)); } cvShowImage("capture_window", frame); key = cvWaitKey(1); if (key == ' ') { break; } // ダミーでフレームを取得(遅延量を少なく出来るように調整) cvQueryFrame(capture); cvQueryFrame(capture); cvQueryFrame(capture); cvQueryFrame(capture); } cvReleaseMemStorage(&cvMStr); cvReleaseCapture(&capture); cvDestroyWindow("capture_window"); cvReleaseHaarClassifierCascade(&cvHCC); return 0; } // 指定した領域の輝度平均値を得る int calcBrightness(CvRect* rect, IplImage* frame) { int x; int y; unsigned char r, g, b, mono; unsigned long sum; sum = 0; // rectで指定された領域サイズでループを回す for (y = rect->y; y<(rect->y + rect->height); y++) { for (x = rect->x; x<(rect->x + rect->width); x++) { b = frame->imageData[frame->widthStep*y + x * 3]; g = frame->imageData[frame->widthStep*y + x * 3 + 1]; r = frame->imageData[frame->widthStep*y + x * 3 + 2]; // モノクロのデータを算出 mono = (unsigned char)((float)r*0.30f + (float)g*0.59f + (float)b*0.11f); sum += mono; } } // 平均値を戻す return(sum / (rect->width*rect->height)); }
<編集3>
編集2で載せましたコードがなぜ正常に実行できないのかがわかりません。
depends.exeを利用して必要なDLLは揃えました。
基のソースコードがラズパイ用であるためでしょうか?
回答5件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。