C ++ OpenCV, IplImage для двойного массива - PullRequest
2 голосов
/ 21 января 2012

Я бы хотел:

(1) преобразовать IplImage размером 20x20 в двойной массив; то

(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]);

Это не работает, программа падает, и я не могу определить причину, но давайте предположим, что это ошибка сегмента ... Кроме того, должен быть элегантный способ сделать то, что я хочу, в стиле Matlab ... .

Я даже не знаю, как убедиться, что данные в массиве данных действительно значения, которые я хочу сравнить с кодовой книгой (Самоорганизованная классификация карт) ... В идеальном мире эти данные должны быть двоичными значениями, вычисляемыми cvThreshold.

Любая помощь будет очень ценится !!!!!

Спасибо !!

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Элегантный способ состоит в том, чтобы

использовать C ++ API OpenCV.

И тогда вы не конвертируете свое изображение в массив, который глуп и не может ничего делать, но конвертируетеваш массив в cv :: Mat, который является мощным!

И тогда вы будете иметь функции, такие как сумма, мин и т. д. все в вашем распоряжении!

  • Вы можете инициализировать резюме:: Mat с std :: vector просто в конструкторе!И тогда вы можете перевернуть его в другую размерность.
  • Вы можете инициализировать cv :: Mat из массива C, используя std :: copy.Да, это работает!
  • Вы можете использовать abs, operator- (), sum, min, нули, как в вашем примере с Matlab.Даже пороговое значение работает довольно схожим образом, хотя есть также cv :: threshold ()

Не стесняйтесь.Начните писать элегантный и чистый код сегодня .

0 голосов
/ 22 января 2012

Ответ:

//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... :)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...