2011-07-03 1 views
0

J'essaie de convertir une image RVB en une image en niveaux de gris. L'image RVB est 160 * 120 * 4, tandis que mon échelle de gris est 160 * 120 * 1. Cependant, il ne me donne pas wat wan mais tout simplement noir et cela prend beaucoup de temps. C'est wat j'ai écrit, s'il vous plaît conseil. MerciConversion d'image en niveaux de gris Turbo C++

int i, j, sum; 
Image = new unsigned char [ 160 * 120 * 1 ]; 
for(int j = 0; j < 120; j++) { 

    for(int i = 0; i < 160; i++) { 
    sum=0; 
     sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
     sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
     sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
     sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
     *Image = sum/4; 

     PaintBox2->Canvas->Pixels[ i ][ j ] = *Image; 
     Image++; 
    } 
} 
+1

Turbo C++ n'existe même plus. Je vous suggère de passer à Visual Studio 2005/2008/2010 et d'obtenir une édition * Express *, gratuite. Commencez ensuite à utiliser OpenCV (une bibliothèque multiplate-forme pour le traitement d'image) pour faire un travail sérieux. – karlphillip

+0

Je suis d'accord avec ce que vous avez dit, plus que tout. Mais changer la plate-forme n'est pas quelque chose que je peux prendre une décision. – Chang

Répondre

1

Il y a plusieurs problèmes dans le code que je peux voir immédiatement. Le plus frappant vient de l'intérieur la plus à l'intérieur pour la boucle:

sum=0; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ]; 
*Image = sum/4; 

Ici, vous avez simplement ajouté la même valeur à sum quatre fois, puis divisé par quatre. Cela rend ces six lignes équivalentes à

*Image = PaintBox1->Canvas->Pixels[ i ][ j ]; 

De toute évidence, vous vouliez réellement faire la moyenne de chaque canal. Si votre image RVB ont été mis en œuvre comme un tableau en trois dimensions, ce chercherais probablement quelque chose comme:

sum = 0; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ][ 0 ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ][ 1 ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ][ 2 ]; 
sum += PaintBox1->Canvas->Pixels[ i ][ j ][ 3 ]; 
*Image = sum/4; 

Cependant, à partir de votre exemple de code, il ressemble à votre image RVB est effectivement utilisé comme une matrice à deux dimensions de entiers (non) signés. Dans ce cas, le code suivant devrait suffire (entiers fournis sont quatre octets sur votre machine):

sum = 0; 
unsigned int pixel = PaintBox1->Canvas->Pixels[ i ][ j ]; 
for(int k = 0; k < 4; ++k) 
{ 
    sum += pixel & 0xFF; 
    pixel >>= 1; 
} 
*Image = sum/4; 

L'autre problème majeur que je vois est que vous ne gardez pas un pointeur au début de votre tableau en niveaux de gris. Vous l'initialisez comme

Image = new unsigned char[ 160 * 120 * 1 ]; 

ce qui est bon. Mais chaque fois à travers la boucle, vous avez écrit

Image++; 

Au contraire, vous devez garder un pointeur au début du tableau, et un pointeur temporaire qui agit comme un itérateur:

// before the for loops 
Image = new unsigned char[ 160 * 120 * 1 ]; 
unsigned char * temp = Image; 

// at the end of the inner for loop: 
temp++; 

Donc, vous ne déplacez que le pointeur temp, alors que Image reste fixe.

+0

Oh, je reçois la partie pointeur. Mais la partie moyenne je l'ai tout à fait, parce que j'ai une valeur RVB, chaque Pixels détient 4 valeurs, x amt de rouge, x amt de bleu, x amt de vert, et enfin un NULL. – Chang

+0

Vous dites que chaque pixel contient 4 valeurs. Sont-ils stockés dans un seul int non signé ou quelque chose? Comment exactement votre image est-elle implémentée? –

+0

Vous pouvez faire correspondre la luminance de l'image RVB source dans l'image en niveaux de gris de destination. Utilisez la formule standard suivante: Y = 0,299 * R + 0,587 * G + 0,114 * B –