C ++ OpenCV,IplImage到双数组

Posted

技术标签:

【中文标题】C ++ OpenCV,IplImage到双数组【英文标题】:C++ OpenCV, IplImage to double array 【发布时间】:2012-01-21 02:31:17 【问题描述】:

我愿意:

(1) 将 20x20 IplImage 转换为双精度数组;那么,

(2) 我想计算这个数组和一个 90x(20x20) 二维双精度数组之间的误差。

在 Matlab 中,很容易做到这一点:

(1)
I_thresh = I_gray<120;
% transformer matrice en vecteur
data(i*30+j,:) = (reshape(I_thresh',size(I_thresh,1)*size(I_thresh,2),1))';

(2)
function[classeEstim] = som_test(sM,testData,dim,prune)

labelsDbl = cvtCellChar2num(sM.labels);
X = zeros(size(sM.codebook,1),dim);

for i=1:size(testData,1)
    for j=1:size(sM.codebook,1)
        X(j,:) = abs(testData(1,1:dim) - sM.codebook(j,1:dim));
    end
    idx = (sum(X,2) == (min(sum(X,2))));
    classeEstim = labelsDbl(idx);
end

在 Matlab 中很容易,但在 C++ 中就很糟糕了......

到目前为止我的代码:

double* data;
int step;
CvSize size;
cvGetRawData(thresReduImg, (uchar**)&data, &step, &size);
step /= sizeof(data[0]);
for(int y = 0; y < size.height; y++, data += step )
    for(int x = 0; x < size.width; x++ )
        data[x] = (double)fabs(data[x]);
//classification
double** X = new double* [HEIGHT];
for (int i = 0; i <= HEIGHT; i++)
    X[i] = new double[WIDTH];
for(int i = 0; i <= HEIGHT; i++)
    for(int j = 0; j <= WIDTH; j++)
        X[i][j] = fabs(data[j] - codebook[i][j]);

这不起作用,程序崩溃,我无法确定原因,但让我们猜测它是 seg 错误......此外,必须有一种优雅的方式来做我想做的事,类似于 Matlab 的方式.. .

我什至不知道如何确保数据数组中的数据确实是 我想与码本比较的值(自组织地图分类)......在完美的世界中,这些数据应该是由 cvThreshold 计算的二进制值。

任何帮助将不胜感激!!!!!!

谢谢!!

【问题讨论】:

没关系,几个小时后它就可以工作了... IplImage* dest = cvCreateImage(cvSize(20,20), 64, 1); cvConvert(thresReduImg, dest); double* data = (double*)dest->imageData; 【参考方案1】:

优雅的方式是

使用 OpenCV 的 C++ API。

然后,您不会将您的图像转换为一个愚蠢且无能为力的数组,而是将您的数组转换为一个强大的 cv::Mat!

然后您就可以使用 sum、min 等函数了!

您可以在构造函数中使用 std::vector 初始化 cv::Mat!然后你可以将它重新包装到其他维度。 您可以使用 std::copy 从 C 数组初始化 cv::Mat。是的,它有效! 您可以像在 Matlab 示例中一样使用 abs、operator-()、sum、min、zeros。甚至阈值的工作方式也非常相似,尽管还有 cv::threshold()

不要犹豫。 今天开始编写优雅简洁的代码。

【讨论】:

请阅读下面的代码。对我来说足够优雅,不需要 cvMat。此外,我从 cvs 加载“codebook”作为双二维数组。而且我需要加倍,因为我会计算 Enclidian 距离。 Mat_... 尽快摆脱 IPLImage。相信我。 好的!谢谢!很抱歉一直在做愚蠢的事情;) 不用抱歉,很多人不知道新的 API,但它确实值得研究,否则你会错过 OpenCV 今天所能提供的大部分乐趣。【参考方案2】:

答案是:

//Preprocessing here, to get a 20x20 binary image...

//transformer l'image seuillee en tableau 1D
double* score = new double[HEIGHT];
int index = 0;
//convertir contenu image seuille au format double FIRST ANSWER (1)
IplImage* dest = cvCreateImage(cvSize(20,20), 64, 1);
cvConvert(thresReduImg, dest);
double* data = (double*)dest->imageData;
//classification
double distance = 0;
//calcul des distances euclidiennes entre le vecteur d'entree
// et chacun des neurones de la carte de Kohonen. SECOND ANSWER (2)
for(int n = 0; n < HEIGHT; n++)

    for(int w = 0; w < WIDTH; w++)
    
        //les donnees sont bien binaires, mais 0 ou 255
        // passer en 0 ou 1.
        if(data[w] == 255)
            data[w] = 1;
        //calcul pour chaque poids du neurone.
        distance += pow(data[w] - codebook[n][w],2);
    
    //calcul distance euclidienne pour le neurone.
    score[n] = sqrt(distance);
    distance = 0;

//on cherche la distance minimale.
double value = score[0];
index = 0;
for(int i = 1; i < HEIGHT; i++)

    if(score[i] <= value)
    
        value = score[i];
        index = i;
    

// Continue... :)

【讨论】:

以上是关于C ++ OpenCV,IplImage到双数组的主要内容,如果未能解决你的问题,请参考以下文章

opencv由二维数组转换图像问题

opencv编程中cvMat到Mat如何进行数据转换?

opencv——IplImage结构

如何将IplImage转换为GLubyte数组?

从 ByteBuffer 到双数组

OpenCV 中 IplImage,CvMat,Mat中的type是怎么回事