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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

4回答

6530閲覧

OpenCVで動画の読み込みがうまくできません。

sh1208

総合スコア14

OpenCV

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2015/12/22 06:44

編集2015/12/23 01:24

以前別のプログラムで動画の読み込みができましたが、今現在取り組んでいるプログラムではうまくいきません。
言語はC++でopencv2.4.9を使用しています。
Os windows8.1 visual studio2013を使っています。
よろしくお願いします。

エラーメッセージ

OpenCV Error: Assertion failed (udata < (uchar*)ptr && ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+16)) in cv::fastFree, file C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\alloc.cpp, line 78

void

1{ 2 if(ptr) 3 { 4 uchar* udata = ((uchar**)ptr)[-1]; 5 CV_DbgAssert(udata < (uchar*)ptr && 6 ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+CV_MALLOC_ALIGN)); 7 free(udata); 8 } 9} 10コード
#include <opencv2/opencv.hpp> //静的リンクライブラリの指定 #include <opencv2/opencv_lib.hpp> #include "Classifier.h" #include "IntegralHistogram.h" #include "MeanShift.h" #include "Common.h" //画像を扱う構造体の宣言 IplImage* imgSource = NULL; //原画像 IplImage* imgResult = NULL; //人検出結果 IplImage* imgGray = NULL; //グレイスケール画像 //クラス CClassifier ob_CL; //Real AdaBoostによる識別 CIntegralHistogram ob_IH; //Integral HistogramによるHOG特徴量算出 CMeanShift ob_MS; //MeanShiftによる検出ウィンドウの統合 int main(){ int i, j, l; int frame = 0; CvCapture *capture = NULL; // カメラキャプチャ用の構造体 //出力ウィンドウの作成 char* winOriginal = "OutputImage"; cvNamedWindow(winOriginal, CV_WINDOW_AUTOSIZE); //検出ウィンドウのパラメータ int window_width = INIT_WINDOW_X; int window_height = INIT_WINDOW_Y; int window_count = 0; int window_ture_count = 0; int tcount = 0; double scale; //HOG特徴量の配列 double feature[FEATURE]; // 動画ファイルを開く if ((capture = cvCaptureFromFile("C:\\opencv\\sources\\samples\\c\\tree.avi")) == NULL) { // ファイルが見つからなかった場合 printf("ファイルが見つかりません\n"); exit(1); } imgSource = cvQueryFrame(capture); //領域確保 imgGray = cvCreateImage(cvGetSize(imgSource), IPL_DEPTH_8U, 1); //aviファイル設定 double fps = 25.0; CvVideoWriter* VideoWriter = cvCreateVideoWriter("C:\\opencv\\sources\\samples\\c\\result.avi", -1, fps, cvGetSize(imgSource), 1); //カラー画像からグレイスケール画像へ変換 cvCvtColor(imgSource, imgGray, CV_BGR2GRAY); //初期化 ob_IH.CreateGradLUT(); ob_CL.init(); ob_MS.Init(imgSource); ob_IH.Init(imgGray); cvReleaseImage(&imgSource); //人検出開始 while (1){ //画像の読み込み imgSource = cvQueryFrame(capture); if (imgSource == NULL) exit(1); printf("frame -> %d\n", frame); //積分画像の初期化 ob_IH.ClearIH(); // 画像サイズを保存 CvSize imageSize = cvGetSize(imgSource); //領域確保 imgResult = cvCreateImage(imageSize, IPL_DEPTH_8U, 3); //カラー画像からグレイスケール画像へ変換 cvCvtColor(imgSource, imgGray, CV_BGR2GRAY); //勾配方向と勾配強度,積分画像の算出 ob_IH.CreateIntegralHistogram(imgGray); //原画像のコピー memcpy(imgResult->imageData, imgSource->imageData, imgSource->width * imgSource->height * 3); //パラメータの初期化 window_width = INIT_WINDOW_X; window_height = INIT_WINDOW_Y; window_count = 0; window_ture_count = 0; //検出ウィンドウのスケール変化 for (scale = MIN_SCALE; scale < MAX_SCALE; scale += STEP_SCALE){ window_width = INIT_WINDOW_X * scale; window_height = INIT_WINDOW_Y * scale; //検出ウィンドウのラスタスキャン for (j = 0; j<imgSource->height - window_height; j += STEP_WIDTH){ for (i = 0; i<imgSource->width - window_width; i += STEP_WIDTH){ //特徴量抽出 ob_IH.Getfeature(feature, i, j, window_width, window_height); //検出ウィンドウが人であるかの識別 if (ob_CL.classifier(feature) == TRUE){ //検出ウィンドウの座標をストック ob_MS.Voting(i + (int)(window_width * 0.5), j + (int)(window_height * 0.5), window_ture_count, scale); window_ture_count++; } } } } //MeanShiftによる検出ウィンドウの統合 ob_MS.MeanShift(); //Nearest Neighborによる検出ウィンドウの統合 tcount = ob_MS.NearestNeighbor(); //人がいると識別された領域を矩形で囲む for (l = 0; l < tcount; l++){ //検出ウィンドウが統合された数がしきい値以下ならば人以外として判別 if (ob_MS.win[l].count >= TH_HEAD_COUNT){ //検出ウィンドウの縦幅と横幅を計算 window_width = INIT_WINDOW_X * ob_MS.win[l].new_scale; window_height = INIT_WINDOW_Y * ob_MS.win[l].new_scale; //検出ウィンドウを矩形で囲む cvRectangle(imgResult, cvPoint(ob_MS.win[l].new_x - window_width * 0.5, ob_MS.win[l].new_y - window_height * 0.5), cvPoint(ob_MS.win[l].new_x + window_width * 0.5, ob_MS.win[l].new_y + window_height * 0.5), CV_RGB(0, 0, 255), 2, 8, 0); } } //人検出結果を保存と出力 cvShowImage(winOriginal, imgResult); cvWaitKey(10); //1画面分の取り込み cvWriteFrame(VideoWriter, imgResult); // 確保したメモリを開放 cvReleaseImage(&imgSource); cvReleaseImage(&imgResult); frame++; } // 確保したメモリを開放 cvReleaseImage(&imgGray); cvReleaseVideoWriter(&VideoWriter); cvReleaseCapture(&capture); return 0; } コード

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

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

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

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

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

Chironian

2015/12/22 10:37

allocで出ている例外ですので、対象が広すぎて見当が付きません。もう少し絞り込んだ方がよいと思います。また、OSやコンパイラの情報も乗せるべきと思います。
sh1208

2015/12/23 01:21

OSはwindows8.1 visual studio2013 を使ってます。 エラーの内容が見当がつかなすぎて、どこから絞ればいいのか途方にくれています。
izkn

2015/12/24 05:35

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
guest

回答4

0

こんにちは。

情報の追加・修正の依頼をする

では書きにくいので、こちらから。

ご提示されているソースを全て精査し、問題がありそうな場所を指摘するって現実的ではないくらい長いソースです。せめて、エラーの場所が特定できていれば、その関連部を見ればよいので何とかなる時もあります。

エラーの内容が見当がつかなすぎて、どこから絞ればいいのか途方にくれています。

今回でているエラーはメモリ・アケーション周りと思われ、それはどこで発生しても可笑しくないエラーですので、我々も同じです。
つまり、どうにかするためにはsh1208さんのところで出ているエラーを再現しないと見当もつかない状態のままです。従って、再現するためにはsh1208さんが他のPCで同じ問題を再現させようとした場合に必要な情報が必要になります。

今回の場合、ざっくり下記情報が不足してます。(実際にやろうとしたら、他にも出てくるかも。)

①ソース・コード
opencvのヘッダは不要ですが、#include "..."でインクルードしているヘッダ群はopencvでは無いはずです。我々も持っていません。

②OSの情報
64bitですか、32bitですか?

③opecvのビルド方法
prebuild版を使われているようなら、ダウンロード元を提示頂くと確実です。
自前ビルドされたなら、そのオプションの与え方ですね。

④aviファイル
これを直接アップすることは難しいでしょう。特定のaviファイルで起きるわけでなく、いくつか試した全てで起きるのであれば、そのことを記載頂ければたぶん大丈夫かと。

で、ここまで書いときながら申し訳ないですが、ボランティアですので、私の方で再現トライできることの「約束」はできません。時間が取れない、再現トライする気力が湧かない、などなど様々な事情でトライしない可能性もあります。
その時はごめんなさい。でも、上記情報は私以外の方がトライする場合でも必要になる可能性が高い情報ですので、無駄にはならない可能性もありますから許して下さい。


【追記】
あっと、もう一点思い至りました。Visual Studioでステップ実行していけば、どこでエラーがでたか分かりませんか?


【追記】
うわっ、かなりの量のソースですね。ソース開示をお薦めしましたが、すいません、質問文に入りきれない量を上げて良いとは思えないです。ボランティアで成り立つシステムである以上出来ることには限界があると思います。

とはいえ、折角開示されたのでビルドできないかやってみましたが、できませんでした。
opencv_lib.hppはご指定場所のOpenCV 2.4.9に入っていないファイルのようです。
MeanShift.cppとClassifier.cppは#includeがないのでコンパイルエラーになります。
すいません、これ以上続けると他の方にも迷惑かけそうですし、私の方での再現トライはこの辺が限界です。

前回の追記で述べたようにステップ実行してエラー箇所を絞り込めませんか? それも無理なのでしたら、こんなに大きなソースの不具合解決は、ここでは難しいように感じます。
例えば、ここで対応してくれる人を探してみては如何でしょうか? 有償ですが、ビジネス・スキルさえあれば無償ポランティアより期待できると思います。

後、マルチ・ポストは結構嫌がられます。避けましょう。

投稿2015/12/23 03:07

編集2015/12/24 06:57
Chironian

総合スコア23272

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

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

sh1208

2015/12/24 05:27

①ソースコード ヘッダファイルも回答の方に投稿しました。 ②OSの情報 64bitです。 ③opecvのビルド方法 http://opencv.org/downloads.html VERSION2.4.9の「OpenCV for Windows」をダウンロードしました。 ④aviファイル いくつかファイルを試しましたが、同じエラーの内容でした。 いろいろご教授いただき感謝しています。お時間があればで構わないので再現していただけるとこちらとしても助かります。 また、並行して自分でもトライしていくつもりです。
yohhoy

2016/08/01 12:49

https://github.com/opencv/opencv/blob/master/modules/core/src/alloc.cpp OpenCV内部のアサーションは fastFree 関数内で検出しているようです。ここからは推測にすぎませんが、(前方)バッファーオーバーランによるメモリ破壊か、そもそもOpenCVで動的確保されていないポインタをfreeしようとしたんだと思います。
guest

0

Common.h

#include <opencv2/opencv.hpp> //静的リンクライブラリの指定 #include <opencv2/opencv_lib.hpp> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <windows.h> #include <mmsystem.h> //1個の検出ウィンドウから得られるHOG特徴量の個数 #define FEATURE 3780 //検出ウィンドウのラスタスキャンを行う初期サイズ #define INIT_WINDOW_X 30 #define INIT_WINDOW_Y 60 //検出ウィンドウの最小スケール #define MIN_SCALE 1.0 //検出ウィンドウの最大スケール #define MAX_SCALE 2.5 //検出ウィンドウのスケールの変化幅 #define STEP_SCALE 0.25 //検出ウィンドウをラスタスキャンする際のずらし幅 #define STEP_WIDTH 8 //検出ウィンドウの統合を行った際に,TH_HEAD_COUNTより少ない場合は人と識別しない #define TH_HEAD_COUNT 3 コード

Classifier.h

#include "common.h" //Real AdaBoostによって作成した検出器のフォルダ #define CLASSIFIER_FILE_DIR "C:\\DataSet\\InputData\\boost.dat" //識別に使用する確率密度分布 #define LUT_DIR "C:\\DataSet\\InputData\\LUT\\" #define POS 1 #define NEG 0 #define TRUE 1 #define FALSE 0 #define LEARNING_NUM 500 //学習回数 #define EPSILON 0.0000000001 //弱識別器の出力不可の回避 #define BIN 64 //確率密度分布(1次元ヒストグラム)のBIN数 #define TH 3.0 //valが0以上の場合は1,それ以外は0 #define SIGN(val) ((val == 0) ? 1 : (val < 0) ? 0 : 1) class CClassifier { public: CClassifier(void); ~CClassifier(void); int init(); int classifier(double feature[]); double Prediction(int learn, double feature[]); int ClassifierFileOpen(); int LUTFileOpen(); private: //弱識別器として選択された特徴量の番号 int m_number[LEARNING_NUM]; //弱識別器の確率密度分布 double m_WeakClassifierLUT[LEARNING_NUM][BIN]; }; コード

Classifier.cpp

CClassifier::CClassifier(void) { } CClassifier::~CClassifier(void) { } //初期化 int CClassifier::init(){ //識別器と確率密度分布の読み込み ClassifierFileOpen(); LUTFileOpen(); return 0; } //検出器の読み込み int CClassifier::ClassifierFileOpen(){ int i; char fname[200]; FILE* fp; sprintf(fname, "%s", CLASSIFIER_FILE_DIR); if ((fp = fopen(fname, "r")) == NULL){ printf("File Open Error\n"); exit(1); } for (i = 0; i<LEARNING_NUM; i++){ fscanf(fp, "%d", &m_number[i]); } fclose(fp); return 0; } //確率密度分布読み込み int CClassifier::LUTFileOpen(){ int i, j; double pos, neg; char fname[200]; int tmp; FILE* fp; for (j = 0; j<LEARNING_NUM; j++){ sprintf(fname, "%s%d.dat", LUT_DIR, j); if ((fp = fopen(fname, "r")) == NULL){ printf("File Open Error\n"); exit(1); } for (i = 0; i<BIN; i++){ fscanf(fp, "%d %lf %lf", &tmp, &pos, &neg); //ポジティブクラス,ネガティブクラスの確率密度分布から弱識別器の出力を予めLUTとして計算 m_WeakClassifierLUT[j][i] = 0.5 * log((pos + EPSILON) / (neg + EPSILON)); } fclose(fp); } return 0; } //弱識別器 double CClassifier::Prediction(int learn, double feature[]){ int tmp; //1次元ヒストグラムで表される確率密度分布のどこのBINにくるかを計算 tmp = (int)(feature[m_number[learn]] * BIN); if (tmp >= BIN){ tmp = BIN - 1; } //LUTから弱識別器の読み込みを返す return m_WeakClassifierLUT[learn][tmp]; } //強識別器 int CClassifier::classifier(double feature[]){ int i; double p, q; double c; p = 0, q = 0; c = 0.0; //学習回数分だけ弱識別器による識別の繰り返し for (i = 0; i<LEARNING_NUM; i++){ c += Prediction(i, feature); } //しきい値による判定 if (c >= TH){ return TRUE; } else{ return FALSE; } } コード

投稿2015/12/24 05:21

sh1208

総合スコア14

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

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

0

IntegralHistogram.h

#define CELL_SIZE 8 //8*8pixel #define BLOCK_SIZE 2 //2*2cell #define PI 3.14 #define LN_E 1.0 #define SET_X_SIZE 64 //低解像度にしたときのXの大きさ #define SET_Y_SIZE 128 //低解像度にしたときのYの大きさ #define ORIENTATION 9 #define CW ( SET_X_SIZE / CELL_SIZE) //セルの横幅 #define CH ( SET_Y_SIZE / CELL_SIZE) //セルの縦幅 #define LUT_SIZE 511 //LUTのサイズ class CIntegralHistogram { public: CIntegralHistogram(void); ~CIntegralHistogram(void); // 勾配方向,勾配強度のLUTを作成 int CreateGradLUT(); // 初期化 int Init(IplImage* img); int InitIH(); int ClearIH(); // 各勾配の積分画像の作成 int CreateIntegralHistogram(IplImage* img); int CompIntegralImage(int image_w, int image_h); int Getfeature(double hog_feature[], int x, int y, int w_size, int h_size); // 正規化 int Normalize(double hog_feature[]); // メモリーの解放 int FreeImg(); private: // 各勾配方向の勾配強度 double** image[ORIENTATION]; double cell_hist[CW][CH][ORIENTATION]; int m_bpp; int m_wStep; int m_Width; int m_Height; double m_magnitudeLUT[LUT_SIZE][LUT_SIZE]; int m_gradLUT[LUT_SIZE][LUT_SIZE]; }; コード

IntegralHistogram.cpp

#include <math.h> // include: create #include "IntegralHistogram.h" CIntegralHistogram::CIntegralHistogram(void) { } CIntegralHistogram::~CIntegralHistogram(void) { } // 初期化 int CIntegralHistogram::Init(IplImage* img) { m_wStep = img->widthStep; m_bpp = ((img->depth & 255) / 8) * img->nChannels; m_Width = img->width; m_Height = img->height; // 勾配方向,勾配強度のLUTを作成 CreateGradLUT(); // 各方向のIntegral Image(9方向分)の領域確保 InitIH(); return 0; } // 勾配方向,勾配強度のLUTを作成 int CIntegralHistogram::CreateGradLUT() { int i, j; double x, y; double grad; // 勾配方向の算出 for (j = 0; j < LUT_SIZE; j++){ // 0から511を-255から255に変換 y = j - 255; for (i = 0; i < LUT_SIZE; i++){ // 0から511を-255から255に変換 x = i - 255; m_magnitudeLUT[j][i] = sqrt(x*x + y*y); //勾配の大きさの計算 grad = atan2(y, x); //ラジアンから角度へ変換 grad = (grad * 180) / PI; grad -= 1.0; //マイナスは反転させる if (grad<0.0){ grad += 360.0; } //0~360度を0~180度にする if (grad>180.0){ grad = grad - 180.0; } //20度ずつにする.9分割 m_gradLUT[j][i] = (int)grad / 20; } } return 0; } // 各方向のIntegral Image(9方向分)の領域確保 int CIntegralHistogram::InitIH() { int i, j, k; // メモリの確保 for (k = 0; k < ORIENTATION; k++){ if ((image[k] = (double**)malloc(m_Height * sizeof(double*))) == NULL){ fprintf(stderr, "Don't allocate memory.\n"); exit(1); } for (j = 0; j < m_Height; j++){ if ((image[k][j] = (double*)malloc(m_Width * sizeof(double))) == NULL){ fprintf(stderr, "Don't allocate memory.\n"); for (i = 0; i < j; i++){ free(image[k][i]); } free(image[k]); exit(1); } } } // 初期化 for (k = 0; k < ORIENTATION; k++){ for (j = 0; j < m_Height; j++){ for (i = 0; i < m_Width; i++){ image[k][j][i] = 0.0; } } } return 0; } //各方向のIntegral Image(9方向分)のメモリクリア int CIntegralHistogram::ClearIH(){ int i, j, k; // 初期化 for (k = 0; k < ORIENTATION; k++){ for (j = 0; j < m_Height; j++){ for (i = 0; i < m_Width; i++){ image[k][j][i] = 0.0; } } } return 0; } // 各方向のIntegral Imageを作成 int CIntegralHistogram::CreateIntegralHistogram(IplImage* img){ int x, y; int xgrad, ygrad; int grad; // 勾配方向 int img_h = img->height; int img_w = img->width; int width_size; unsigned char* imgSource = (unsigned char*)img->imageData; // y軸方向の移動 for (y = 0; y < img_h; y++){ width_size = y * m_wStep; // x軸方向の移動 for (x = 0; x < img_w; x++){ //差分 //difference integral if (x == 0){ xgrad = imgSource[width_size + (x + 0)] - imgSource[width_size + (x + 1)]; } else if (x == img_w - 1){ xgrad = imgSource[width_size + (x - 1)] - imgSource[width_size + (x + 0)]; } else{ xgrad = imgSource[width_size + (x - 1)] - imgSource[width_size + (x + 1)]; } if (y == 0){ ygrad = imgSource[(y + 0)*m_wStep + x] - imgSource[(y + 1)*m_wStep + x]; } else if (y == img_h - 1){ ygrad = imgSource[(y - 1)*m_wStep + x] - imgSource[(y + 0)*m_wStep + x]; } else{ ygrad = imgSource[(y - 1)*m_wStep + x] - imgSource[(y + 1)*m_wStep + x]; } xgrad = xgrad + 255; ygrad = ygrad + 255; // 勾配方向 grad = m_gradLUT[ygrad][xgrad]; // 勾配強度 image[grad][y][x] = m_magnitudeLUT[ygrad][xgrad]; } } // 各方向のIntegral Imageの算出 CompIntegralImage(img_w, img_h); return 0; } // 各方向のIntegral Imageの算出 int CIntegralHistogram::CompIntegralImage(int image_w, int image_h){ int i, j, k; for (k = 0; k < ORIENTATION; k++){ // y軸方向の加算 for (j = 1; j < image_h; j++){ for (i = 0; i < image_w; i++){ image[k][j][i] = image[k][j - 1][i] + image[k][j][i]; } } // x軸方向の加算 for (j = 0; j < image_h; j++){ for (i = 1; i < image_w; i++){ image[k][j][i] = image[k][j][i - 1] + image[k][j][i]; } } } return 0; } // 指定範囲内のintegral imageを算出 int CIntegralHistogram::Getfeature(double feature[], int x, int y, int w_size, int h_size){ int p, q, k; int x1, x2, y1, y2; // 1セルが何ピクセルか算出 int iw = w_size / CW; int ih = h_size / CH; //領域内の勾配方向ヒストグラムの作成 for (q = 0; q < CH; q++){ y1 = y + ih * q; y2 = y1 + ih - 1; for (p = 0; p < CW; p++){ x1 = x + iw * p; x2 = x1 + iw - 1; if (x1 == 0){ if (y1 == 0){ for (k = 0; k < ORIENTATION; k++){ cell_hist[p][q][k] = image[k][y2][x2]; } } else{ for (k = 0; k < ORIENTATION; k++){ cell_hist[p][q][k] = image[k][y2][x2] - image[k][y1 - 1][x2]; } } } else{ if (y1 == 0){ for (k = 0; k < ORIENTATION; k++){ cell_hist[p][q][k] = image[k][y2][x2] - image[k][y2][x1 - 1]; } } else{ for (k = 0; k < ORIENTATION; k++){ cell_hist[p][q][k] = (image[k][y1 - 1][x1 - 1] + image[k][y2][x2]) - (image[k][y2][x1 - 1] + image[k][y1 - 1][x2]); } } } } } // ヒストグラムの正規化と特徴量の取得 Normalize(feature); return 0; } //正規化したHOG特徴量の取得 int CIntegralHistogram::Normalize(double feature[]) { int i, j, p, q, k; int c = 0; double sum_magnitude = 0.0; double e = LN_E; double div_regular; int box_w = CW - BLOCK_SIZE + 1; int box_h = CH - BLOCK_SIZE + 1; //y軸方向 for (q = 0; q < box_h; q++){ //x軸方向 for (p = 0; p < box_w; p++){ //y軸方向のセル内の移動 for (j = 0; j < BLOCK_SIZE; j++){ //x軸方向のセル内の移動 for (i = 0; i < BLOCK_SIZE; i++){ for (k = 0; k < ORIENTATION; k++){ //正規化のためヒストグラムの総和の二乗を求める sum_magnitude += cell_hist[p + i][q + j][k] * cell_hist[p + i][q + j][k]; } } } div_regular = 1.0 / sqrt(sum_magnitude + e); //y軸方向のセル内の移動 for (j = 0; j < BLOCK_SIZE; j++){ //x軸方向のセル内の移動 for (i = 0; i < BLOCK_SIZE; i++){ //ヒストグラムの正規化 for (k = 0; k < ORIENTATION; k++){ // あらかじめ計算しておいた除数でかける feature[c] = cell_hist[p + i][q + j][k] * div_regular; //printf("%f\n", feature[c] ); c++; } } } sum_magnitude = 0.0; } } return 0; } // メモリの解放 int CIntegralHistogram::FreeImg() { int j, k; for (k = 0; k < ORIENTATION; k++){ for (j = 0; j < m_Height; j++){ free(image[k][j]); } free(image[k]); } return 0; } コード

投稿2015/12/24 05:15

sh1208

総合スコア14

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

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

0

MeanShift.h

//インクルードファイル指定 #include <opencv2/opencv.hpp> //静的リンクライブラリの指定 #include <opencv2/opencv_lib.hpp> #include <math.h> #include <stdio.h> #include <time.h> #define PI 3.14 #define RADIUS 30.0//20.0 //検出ウィンドウの統合範囲 #define SCALE_RADIUS 0.5 //スケール空間統合範囲(バンド幅) class CMeanShift { public: CMeanShift(void); ~CMeanShift(void); int Init(IplImage* img); int Voting(int w, int h, int count, double scale); int MeanShift(); int NearestNeighbor(); typedef struct{ int old_x; int old_y; int new_x; int new_y; double old_scale; double new_scale; int count; }Window; struct Window win[4000]; private: int m_Width; int m_Height; int m_ImageSize; int bpp; int wStep; int m_count; }; コード

MeanShift.cpp

CMeanShift::CMeanShift(void) { } CMeanShift::~CMeanShift(void) { } //初期化 int CMeanShift::Init(IplImage* img){ m_Width = img->width; m_Height = img->height; m_ImageSize = m_Width*m_Height; wStep = img->widthStep; bpp = ((img->depth & 255) / 8) * img->nChannels; return 0; } //正規分布状に投票 int CMeanShift::Voting(int w, int h, int count, double scale){ win[count].old_x = w; win[count].old_y = h; win[count].old_scale = scale; m_count = count; return 0; } int CMeanShift::MeanShift(){ int i, j; double x, y, xi, yi, move_x, move_y, move_scale, Kernel, Kernel1, Kernel2; double scale, scalei; double sum_x = 0.0, sum_y = 0.0, sum_scale = 0.0, sum_w = 0.0; double radius; // 検出座標数だけ繰り返し for (i = 0; i<m_count; i++){ x = win[i].old_x; y = win[i].old_y; scale = win[i].old_scale; while (1){ //初期化 sum_x = sum_y = sum_scale = sum_w = 0.0; //密度計算 for (j = 0; j<m_count; j++){ xi = win[j].old_x; yi = win[j].old_y; scalei = win[j].old_scale; //x-y空間のカーネル関数 Kernel1 = -(((x - xi) * (x - xi) + (y - yi) * (y - yi)) / (RADIUS * RADIUS)); Kernel1 = exp(Kernel1); //scale空間のカーネル関数 Kernel2 = -(((scale - scalei) * (scale - scalei)) / (SCALE_RADIUS * SCALE_RADIUS)); Kernel2 = exp(Kernel2); //カーネルの統合 Kernel = Kernel1 * Kernel2; sum_x += xi * Kernel; sum_y += yi * Kernel; sum_scale += scalei * Kernel; sum_w += Kernel; } // 移動量の計算 move_x = (sum_x / sum_w) - x; move_y = (sum_y / sum_w) - y; move_scale = (sum_scale / sum_w) - scale; x = x + move_x; y = y + move_y; scale = scale + move_scale; // 閾値以下に収束するまで if (move_x > -0.1 && move_x < 0.1 && move_y > -0.1 && move_y < 0.1 && move_scale > -SCALE_RADIUS && move_scale < SCALE_RADIUS){ break; } } // Mean-Shift後位置保存 win[i].new_x = int(x); win[i].new_y = int(y); win[i].new_scale = scale; } return 0; } int CMeanShift::NearestNeighbor(){ int i, j; int count = 0; double d; double th = RADIUS; int flag; struct Window win2[4000]; memset(win2, 0, sizeof(win2)); int outcount; for (j = 0; j<m_count; j++){ flag = 0; if (win[j].new_x != -100){ win2[count].new_x = win[j].new_x; win2[count].new_y = win[j].new_y; win2[count].new_scale = win[j].new_scale; win2[count].count++; count++; flag = 1; } if (flag == 1){ outcount = 0; for (i = j; i<m_count; i++){ d = ((win[j].new_x - win[i].new_x) * (win[j].new_x - win[i].new_x) + (win[j].new_y - win[i].new_y) * (win[j].new_y - win[i].new_y)); if (d < (th * th) && i != j){ win2[count - 1].count++; win2[count - 1].new_x = (win2[count - 1].new_x + win[i].new_x) / 2.0; win2[count - 1].new_y = (win2[count - 1].new_y + win[i].new_y) / 2.0; win2[count - 1].new_scale = (win2[count - 1].new_scale + win[i].new_scale) / 2.0; win[i].new_x = -100; win[i].new_y = -100; win[i].new_scale = -1.0; win[i].count = 0; outcount++; } } } } memcpy(win, win2, sizeof(win)); return count; } コード

投稿2015/12/24 05:11

sh1208

総合スコア14

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問