Question

Je suis à l'aide d'OpenCV pour itérer sur une image et de trouver la couleur de chaque pixel, voici le code que j'utilise:

IplImage* img = cvLoadImage("c:\\test.png");

int pixels = img->height * img->width;
int channels = img->nChannels;

for (int i = 0; i < pixels*channels; i+= channels)
{

    unsigned char red = img->imageData[i + 2];
    unsigned char green = img->imageData[i + 1];
    unsigned char blue = img->imageData[i];

    outputRGBValues(red, green, blue);
    if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
    {
        count++;
    }
}
cvReleaseImage(&img);

Quand je le lance, il outputRGBValues sorties de valeurs négatives.Le plus souvent R, G, B = -1, mais de temps en temps d'autres nombres négatifs et une poignée de nombres positifs.J'ai entendu quelque chose à propos de la mémoire non initialisée contenu, et les pixels n'étant pas affectés à la mémoire correctement.Mais je suis ne comprends pas vraiment et certainement ne savez pas comment le résoudre.Ce que je fais mal et comment puis-je résoudre ce problème?

Mise à JOUR

Après la fixation de la code (comme ci-dessus) avec fschmitt de changements, je suis un peu plus près. Cette est l'image que je suis en utilisant, si ça aide.Assez difficile à voir, mais c'est juste un 5*3 'V' de pixels noirs avec une verte en bas.

L'exécution du code sur elle, j'obtiens ce résultat:

0 0 0
255 255 255
255 255 255
255 255 255
0 0 0
255 255 186
0 0 255
255 255 0
And it continues

Les 5 premières lignes sont très bien, exactement ce qu'ils devraient être.C'est la ligne du haut de l'image.La ligne suivante, à partir de la ligne 6 est faux.Il devrait être:

255 255 255
255 255 255
0 0 0

Je ne suis pas sûr de ce qui cause cela.Comment peut-il travailler pour la ligne du haut et pas le second?Est-il une sorte de décalage, et de prendre la valeur d'un bit vers la gauche de l'endroit où il se doit?

Était-ce utile?

La solution

Essayez ceci:

IplImage* img = cvLoadImage("c:\\test.png");

for (int i = 0; i < img->height; i++)
{
    for (int j = 0; j < img->width; j += img->nChannels)
    {
        unsigned char red = img->imageData[i * img->widthStep + j + 2];
        unsigned char green = img->imageData[i * img->widthStep + j + 1];
        unsigned char blue = img->imageData[i * img->widthStep + j];

        outputRGBValues(red, green, blue);
        if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
        {
            count++;
        }
    }
}
cvReleaseImage(&img);

Autres conseils

Je ne comprends pas pourquoi vous accédez à des données de pixels à l'aveuglette (en 1D index) alors que vous savez déjà l'importance de l'image (prouvé par l'utilisation de IplImage::height et IplImage::width) et opencv fournit une fonction permettant d'accéder valeur de pixel (cvGet*D).

Vous obtenez des valeurs bizarres dans le pointeur direct d'accès parce que vous n'avez pas un facteur dans l'octet de remplissage effectué par OpenCV.Vous pouvez trouver en 8 bits des images, (largeur*nChannels <= widthStep) pour cette raison.

Une rapide révision du code peut être comme suit:

IplImage* img = cvLoadImage("c:\\test.png");
for(int iRow=0; iRow<img->height; ++iRow)
{
    for(int iCol=0; iCol<img->width; ++iCol)
    {
        CvScalar pixelVal = cvGet2D( img, iRow, iCol);
        unsigned char red = pixelVal.val[2];
        unsigned char green = pixelVal.val[1];
        unsigned char blue = pixelVal.val[0];

        outputRGBValues(red, green, blue);
        if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
        {
            count++;
        }
    }
}
cvReleaseImage(&img);

Aussi, notez que généralement OpenCV organiser les données dans BGR format, qui peut vérifiée au IplImage::channelSeq. Ne pas confondre, par IplImage::colorModel, qui raconte le modèle de couleur.

Je vais aller avec Paul R suggestion que vous devriez trouver une référence et de comprendre la bibliothèque avant de tenter de les utiliser.

Je n'ai jamais utilisé d'OpenCV, mais j'imagine que cvCreateImage ne pas initialiser le contenu de l'image, et certainement pas à quelque chose de valable.

Quelques questions se posent ici:

  • Vous devez remplir l'image avec des données significatives
  • Selon la façon dont l'image a été construit, vous pouvez avoir troqué le rouge et le bleu
  • Vous devez utiliser unsigned char rouge
  • Vous déclarez un vecteur pour chaque pixel et ne l'utilisez pas
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top