web-dev-qa-db-fra.com

c ++ et opencv obtiennent et définissent la couleur de pixel sur Mat

J'essaie de définir une nouvelle valeur de couleur pour un pixel dans une image cv :: Mat. Mon code est ci-dessous:

    Mat image = img;
    for(int y=0;y<img.rows;y++)
    {
        for(int x=0;x<img.cols;x++)
        {
        Vec3b color = image.at<Vec3b>(Point(x,y));
        if(color[0] > 150 && color[1] > 150 && color[2] > 150)
        {
            color[0] = 0;
            color[1] = 0;
            color[2] = 0;
            cout << "Pixel >200 :" << x << "," << y << endl;
        }
        else
        {
            color.val[0] = 255;
            color.val[1] = 255;
            color.val[2] = 255;
        }
    }
    imwrite("../images/imgopti"+to_string(i)+".tiff",image);

Il semble obtenir le bon pixel en sortie (avec cout), mais dans l'image en sortie (avec imwrite), les pixels concernés ne sont pas modifiés. J'ai déjà essayé d'utiliser color.val [0] .. Je n'arrive toujours pas à comprendre pourquoi les couleurs de pixel de l'image de sortie ne changent pas. Merci

37
grll

Vous avez tout fait sauf copier la nouvelle valeur de pixel dans l'image.

Cette ligne prend une copie du pixel dans une variable locale:

Vec3b color = image.at<Vec3b>(Point(x,y));

Ainsi, après avoir modifié color selon vos besoins, réglez-le comme suit:

image.at<Vec3b>(Point(x,y)) = color;

Donc, en gros, quelque chose comme ça:

Mat image = img;
for(int y=0;y<img.rows;y++)
{
    for(int x=0;x<img.cols;x++)
    {
        // get pixel
        Vec3b color = image.at<Vec3b>(Point(x,y));

        // ... do something to the color ....

        // set pixel
        image.at<Vec3b>(Point(x,y)) = color;
    }
}
59
Roger Rowland

il suffit d'utiliser une référence:

Vec3b & color = image.at<Vec3b>(y,x);
color[2] = 13;
15
berak

Je n'utiliserais pas .at pour des raisons de performances.

Définir une structure:

//#pragma pack(Push, 2) //not useful (see comments below)
struct RGB {
    uchar blue;
    uchar green;
    uchar red;  };

Et utilisez-le comme ceci sur votre image cv :: Mat:

RGB& rgb = image.ptr<RGB>(y)[x];

image.ptr (y) vous donne un pointeur sur la ligne de balayage y. Et parcourez les pixels avec des boucles de x et y

13
Flocke