Announce

PukiWiki contents have been moved into SONOTS Plugin (20070703)

opencv

Table of Contents

Snippets

反転?

まず avi ファイルを読み込んだ時点で。

img = cvQueryFrame( cap );
#if defined(WIN32) || defined(WIN64)
img->origin = 0;
cvFlip( img, img, 0 );
#endif

いや、

img = cvQueryFrame( cap );
if( img->origin != IPL_ORIGIN_TL ) cvFlip( img, img ); // prevent flipping on Windows

こうか?いや、やはり上のほうが確実っぽい

cvCvtColor, cvCopy などを呼ぶと WIN32 では画像が反転する模様

cvCvtColor( src, dist, CV_BGR2GRAY );
#if defined(WIN32) || defined(WIN64)
    dist->origin = img->dist;
#endif

カナ?

CVAPI

CVAPI(int) などの CVAPI は cxcore/include/cxtypes.h にある

extern "C" __declspec(dllexport) int __cdecl

みたいな形になる模様。環境依存配慮

ゴミ

CvEM を GmmPdf として使いたい

うーん、ダメだ。

#ifdef _MSC_VER
#pragma warning(disable:4996)
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "cvaux.lib")
#pragma comment(lib, "highgui.lib")
#pragma comment(lib, "ml.lib")
#endif

#include "cv.h"
#include "cvaux.h"
#include "ml.h"

#ifndef CV_EMEXT_INCLUDED
#define CV_EMEXT_INCLUDED


CvEM::CvEM( const CvMat* samples, const CvMat* sample_idx, CvEMParams params, CvMat* labels )
{
    int D = params.means->cols;
    CvVectors train_data;
    train_data.count = params.weights->rows;
    train_data.dims = D;
    set_params( params, train_data );
}

/*
// Example)
//    const int D = 2;
//    const int N = 3;
//    const int K = 2;
//
//    double vs[] = { 3, 3,
//                    4, 4,
//                    5, 5 }; // row vectors
//    double ms[] = { 3, 3, 
//                    5, 5 }; // row vectors
//    double cs0[] = { 1, 0,
//                     0, 1 };
//    double cs1[] = { 1, 0.1,
//                     0.1, 1 };
//    double ws[] = { 0.5, 0.5 };
//
//    CvMat vecs = cvMat(N, K, CV_64FC1, vs);
//    CvMat means = cvMat(K, D, CV_64FC1, ms);
//    CvMat **covs = (CvMat**)cvAlloc( K * sizeof(*covs) );
//    covs[0] = &cvMat(D, D, CV_64FC1, cs0);
//    covs[1] = &cvMat(D, D, CV_64FC1, cs0);
//    CvMat weights = cvMat(1, K, CV_64FC1, ws);
//    CvMat *probs = cvCreateMat(N , K, CV_64FC1);
//    CvEM em;
//    em.GmmPdf( &vecs, &means, covs, &weights, probs );
//    cvMatPrint( probs );
//    cvReleaseMat( &probs );
//    cvFree( &covs );
//     
// @param CvMat* samples N x D sample vector
// @param CvMat* means K x D mean vector for each cluster
// @param CvMat** covs K x (D x D) covariance matrix for each cluster
// @param CvMat* weights 1 x K weights
// @param CvMat* probs N x K or N x 1 computed probabilities. 
//     If N x K, probs for each cluster is stored instead of sum of them ( N x 1 )
*/
void CvEMGmmPdf( const CvMat* samples, const CvMat* means, CvMat** covs, const CvMat* weights, CvMat* probs )
{
    int N = samples->rows;
    int D = samples->cols;
    int K = means->rows;
    int type = samples->type;
    CvEMParams params;
    params.covs      = (const CvMat**)covs;
    params.means     = means;
    params.weights   = weights;
    params.probs     = probs;
    params.nclusters = K;
    params.cov_mat_type = CvEM::COV_MAT_GENERIC;

    //CvEM em_model( NULL, NULL, params, NULL );
    CvMat* sample = cvCreateMat( 1, D, type );
    CvMat* prob   = cvCreateMat( 1, probs->cols, type );
    for( int n = 0; n < N; n++ )
    {
        cvGetRow( samples, sample, n );
        //em_model.predict( sample, prob );
        for( int k = 0; k < probs->cols; k++ )
        {
            cvmSet( probs, n, k, cvmGet( prob, 0, k ) );
        }
    }
    cvReleaseMat( &sample );
    cvReleaseMat( &prob );
}

#endif

Mask And

matlab なら no-loop のほうが短くなるのだが・・・・

        IplImage* imgB    = cvCreateImage( cvGetSize(img), img->depth, 1 );
        IplImage* imgG    = cvCreateImage( cvGetSize(img), img->depth, 1 );
        IplImage* imgR    = cvCreateImage( cvGetSize(img), img->depth, 1 );
        IplImage* tmpMask = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );

        cvSplit( img, imgB, imgG, imgR, NULL );
        cvSet( mask, cvScalarAll(1) );

        cvThreshold( imgR, tmpMask, 95, 1, CV_THRESH_BINARY );
        cvAnd( tmpMask, mask, mask );
        cvThreshold( imgG, tmpMask, 40, 1, CV_THRESH_BINARY );
        cvAnd( tmpMask, mask, mask );
        cvThreshold( imgB, tmpMask, 20, 1, CV_THRESH_BINARY );
        cvAnd( tmpMask, mask, mask );

        IplImage* maxRGB = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        IplImage* minRGB = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        cvMax( imgR, imgG, maxRGB );
        cvMax( imgB, maxRGB, maxRGB );
        cvMin( imgR, imgG, minRGB );
        cvMin( imgB, minRGB, minRGB );
        cvAbsDiff( maxRGB, minRGB, tmpMask );
        cvThreshold( tmpMask, tmpMask, 15, 1, CV_THRESH_BINARY );
        cvAnd( tmpMask, mask, mask );
        cvRelease( &maxRGB );
        cvRelease( &minRGB );

        cvAbsDiff( imgR, imgG, tmpMask );
        cvThreshold( tmpMask, tmpMask, 15, 1, CV_THRESH_BINARY );
        cvAnd( tmpMask, mask, mask );
        cvCmp( imgR, imgB, tmpMask, CV_CMP_GT );
        cvAnd( tmpMask, mask, mask );
        cvCmp( imgR, imgG, tmpMask, CV_CMP_GT );
        cvAnd( tmpMask, mask, mask );

        cvReleaseImage( &imgB );
        cvReleaseImage( &imgG );
        cvReleaseImage( &imgR );
        cvReleaseImage( &tmpMask );

YCbCRMAHAL Skincolor

        //case CV_SKINCOLOR_YCrCbMAHAL:
        //[2] Son Lam Phung; Bouzerdoum, A.; Chai, D., "A novel skin color model in YCbCr color space and its application to human face detection," Image Processing. 2002. Proceedings. 2002 International Conference on , vol.1, no., pp. I-289-I-292 vol.1, 2002
        /*
        #define MAX_DATA 500
        #define DEMIENSION 3
        int count;             //データの個数
        double distance;       //マハラノビス距離
        CvMat *data[MAX_DATA]; //クラス
        CvMat *result        = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //共分散行列
        CvMat *inversecovar  = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //逆共分散行列
        CvMat *average       = cvCreateMat( DIMENSION, 1, CV_32F);         //平均ベクトル
        CvMat *input         = cvCreateMat( DIMENSION, 1, CV_32F);         //比較するベクトル

        //クラスの読み込み
        //この場合dataの各要素は高さDIMENSION,幅1のベクトル
        count = ReadData( data, MAX_DATA);
        ReadInput( input);                                       //↓クラスから共分散行列を計算
        cvCalcCovarMatrix( data, count, result, average, CV_COVAR_NORMAL | CV_COVAR_SCALE);
        cvInvert( result, inversecovar, CV_SVD);                 //逆行列計算
        distance = cvMahalanobis( average, input, inversecovar); //計算した逆共分散行列からマハラノビス距離を計算
        */

        //    // Rcb \in [75,135], Rcr \in [130,180]
        //    // (75,118,143), (138,110,150), (184,111,147)
        //    double m1[] = { 75, 118, 143 };
        //    double m2[] = { 138, 110, 150 };
        //    double m3[] = { 184, 111, 147 };
        //    CvMat mean1 = cvMat( 3, 1, CV_64FC1, m1 );
        //    CvMat mean2 = cvMat( 3, 1, CV_64FC1, m2 );
        //    CvMat mean3 = cvMat( 3, 1, CV_64FC1, m3 );
        //    CvMat cluster_data[img->nSize];
        //    CvMat *cov1 = cvCreateMat( 3, 3, CV_64FC1 );
        //    CvMat *cov2 = cvCreateMat( 3, 3, CV_64FC1 );
        //    CvMat *cov3 = cvCreateMat( 3, 3, CV_64FC1 );

        //    IplImag* imgYCrCb = cvCreateImage( cvGetSize(img), img->depth, 1 );
        //    cvCvtColor( img, imgYCrCb, CV_BGR2YCrCb );

        //    float thresh1 = 255/3.0;
        //    float thresh2 = 2 * thresh1;

        //    IplImag* cluster_mask1 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        //    IplImag* cluster_mask2 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        //    IplImag* cluster_mask3 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        //    cvZero( cluster1 ); cvZero( cluster2 ); cvZero( cluster3 );
        //    int nCluster1 = 0, nCluster2 = 0, nCluster3 = 0;
        //    int num = 0;
        //    double v[3];
        //    for( int i = 0; i < img->height; i++ )
        //    {
        //        for( int j = 0; j < img->width; j++ )
        //        {
        //            v[0] = imgYCrCb->imageData[img->widthStep * i + j * 3];
        //            v[1] = imgYCrCb->imageData[img->widthStep * i + j * 3 + 1];
        //            v[2] = imgYCrCb->imageData[img->widthStep * i + j * 3 + 2];
        //            if( v[0] < thresh1 )
        //            {
        //                cluster1->imageData[img->widthStep * i + j] = 1;
        //                cluster_data[n++] = cvMat( 3, 1, CV_64FC1, v );
        //                nCluster1++;
        //            }
        //            else if( v[0] < thresh 2)
        //            {
        //                cluster2->imageData[img->widthStep * i + j] = 1;
        //                nCluster2++;
        //            }
        //            else
        //            {
        //                cluster3->imageData[img->widthStep * i + j] = 1;
        //                nCluster3++;
        //            }
        //        }
        //    }
        //    cvCalcCovarMatrix( &cluster_data, nCluster1, cov1, mean1, CV_COVAR_NORMAL | CV_COVAR_SCALE);
        //    CvMat *invcov1 = cvCreateMat( 3, 3, CV_64FC1 );
        //    CvMat *invcov2 = cvCreateMat( 3, 3, CV_64FC1 );
        //    CvMat *invcov3 = cvCreateMat( 3, 3, CV_64FC1 );
        //    cvInvert( cov1, invcov1, CV_SVD);
        //    cvInvert( cov2, invcov2, CV_SVD);
        //    cvInvert( cov3, invcov3, CV_SVD);
        //    cvReleaseMat( &cov1 );
        //    cvReleaseMat( &cov2 );
        //    cvReleaseMat( &cov3 );

        //    for( int i = 0; i < mat->rows; i++ )
        //    {
        //        for( int j = 0; j < mat->cols; j++ )
        //        {
        //            double dist1 = cvMahalanobis( mean1, cvmGet( data, i, j ), invcov1 );
        //            double dist2 = cvMahalanobis( mean2, cvmGet( data, i, j ), invcov2 );
        //            double dist3 = cvMahalanobis( mean3, cvmGet( data, i, j ), invcov3 );
        //            if( min( dist1, min( dist2, dist3 ) ) < thresh )
        //            {
        //                mask->imageData[img->widthStep * i + j] = 1;
        //            }
        //        }
        //    }


        //    for( int y = 0; y < img->height; y++ )
        //    {
        //        for( int x = 0; x < img->width; x++ )
        //        {
        //            v[0] = imgYCrCb->imageData[img->widthStep * y + x * 3];
        //            v[1] = imgYCrCb->imageData[img->widthStep * y + x * 3 + 1];
        //            v[2] = imgYCrCb->imageData[img->widthStep * y + x * 3 + 2];
        //            if( ( v[2] < 130 || v[2] > 180 ) || ( v[1] < 75 || v[1] > 135 ) )
        //            {
        //                mask->imageData[img->widthStep * y + x] = 0;
        //                continue;
        //            }
        //            
        //        }
        //    }

        //    double v[3];
        //    cvSet( mask, cvScalarAll(1) );
        //    for( int y = 0; y < img->height; y++ )
        //    {
        //        for( int x = 0; x < img->width; x++ )
        //        {
        //            v[0] = imgYCrCb->imageData[img->widthStep * y + x * 3];
        //            v[1] = imgYCrCb->imageData[img->widthStep * y + x * 3 + 1];
        //            v[2] = imgYCrCb->imageData[img->widthStep * y + x * 3 + 2];
        //            if( ( v[2] < 130 || v[2] > 180 ) || ( v[1] < 75 || v[1] > 135 ) )
        //            {
        //                mask->imageData[img->widthStep * y + x] = 0;
        //                continue;
        //            }
        //            
        //        }
        //    }