Reputation: 1715
I'd like to :
(1) convert a 20x20 IplImage to a double array; then,
(2) I'd like to compute the error between this array and a 90x(20x20) 2 dimensional array of double type.
In Matlab, it is easily done like this:
(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
It is very easy in Matlab, but in C++ it's awful...
My code so far:
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]);
This does not work, the program crashes and I can't identify the reason, but let's guess it's seg fault... Beside, there must be an elegant way to do what I want, a Matlab-like way...
I don't even know how to make sure that the datas in the data array are indeed the values I want to compare to codebook (Self organized map classification)... In a perfect world, those datas should be the binary values computed by cvThreshold.
Any help will be very much appreciated!!!!!
Thanks !!
Upvotes: 2
Views: 1802
Reputation: 52357
The elegant way would be to
And then, you would not convert your image to an array which is dumb and cannot do anything, but convert your array to a cv::Mat, which is powerful!
And then you would have functions like sum, min etc. all at your disposal!
Don't hesitate. Start writing elegant and clean code today.
Upvotes: 2
Reputation: 1715
The answer is :
//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... :)
Upvotes: 0