80 votes

L'accès à certains pixels RVB valeur dans openCV

J'ai recherché sur internet et stackoverflow à fond, mais je n'ai pas trouvé de réponse à ma question:

Comment puis-je obtenir/définir (les deux) valeur RVB de certains (donné par les coordonnées x,y) des pixels dans OpenCV? Ce qui est important-je suis en train d'écrire en C++, l'image est stockée dans la cv::Mat variable. Je sais qu'il est un IplImage() de l'opérateur, mais IplImage n'est pas très à l'aise dans l'utilisation-pour autant que je sais qu'il vient de C API.

Oui, je suis consciente qu'il y avait déjà ce Pixel accès dans OpenCV 2.2 thread, mais c'est seulement en noir et blanc des images bitmap.

EDIT:

Merci beaucoup pour toutes vos réponses. Je vois, il y a de nombreuses façons d'obtenir/définir les valeurs RVB des pixels. J'ai encore une idée de mon amie merci Benny! C'est très simple et efficace. Je pense que c'est une question de goût de celui qui vous choisissez.

Mat image;

(...)

Point3_<uchar>* p = image.ptr<Point3_<uchar> >(y,x);

Et puis vous pouvez lire/écrire les valeurs RVB avec:

p->x //B
p->y //G
p->z //R

100voto

Boaan Points 1809

Essayez les solutions suivantes:

cv::Mat image = ...do some stuff...;

image.at<cv::Vec3b>(y,x); vous donne le RVB (il peut être commandé comme BGR) vecteur de type cv::Vec3b

image.at<cv::Vec3b>(y,x)[0] = newval[0];
image.at<cv::Vec3b>(y,x)[1] = newval[1];
image.at<cv::Vec3b>(y,x)[2] = newval[2];

19voto

aardvarkk Points 4381

Le faible niveau moyen serait d'accéder à la matrice de données directement. Dans une image RVB (qui, je crois OpenCV généralement des magasins de BGR), et en supposant que votre cv::Mat variable est appelé frame, vous pouvez obtenir la valeur de bleu à l'emplacement (x, y) (à partir du haut à gauche) de cette façon:

frame.data[frame.channels()*(frame.rows*y + x)];

De même, pour obtenir B, G et R:

uchar b = frame.data[frame.channels()*(frame.cols*y + x) + 0];    
uchar g = frame.data[frame.channels()*(frame.cols*y + x) + 1];
uchar r = frame.data[frame.channels()*(frame.cols*y + x) + 2];

Notez que ce code suppose que la foulée est égale à la largeur de l'image.

2voto

ShannonLiu Points 11

Un morceau de code est plus facile pour les gens qui ont ce problème. Je partage mon code et vous pouvez l'utiliser directement. Veuillez noter que OpenCV magasin de pixels BGR.

cv::Mat vImage_; 

if(src_)
{
    cv::Vec3f vec_;

    for(int i = 0; i < vHeight_; i++)
        for(int j = 0; j < vWidth_; j++)
        {
            vec_ = cv::Vec3f((*src_)[0]/255.0, (*src_)[1]/255.0, (*src_)[2]/255.0);//Please note that OpenCV store pixels as BGR.

            vImage_.at<cv::Vec3f>(vHeight_-1-i, j) = vec_;

            ++src_;
        }
}

if(! vImage_.data ) // Check for invalid input
    printf("failed to read image by OpenCV.");
else
{
    cv::namedWindow( windowName_, CV_WINDOW_AUTOSIZE);
    cv::imshow( windowName_, vImage_); // Show the image.
}

0voto

Jacob Points 22306

La version actuelle permet à l' cv::Mat::at fonction pour gérer 3 dimensions. Donc, pour l' Mat objet m, m.at<uchar>(0,0,0) devrait fonctionner.

-6voto

user537723 Points 33
const double pi = boost::math::constants::pi<double>();

cv::Mat distance2ellipse(cv::Mat image, cv::RotatedRect ellipse){
    float distance = 2.0f;
    float angle = ellipse.angle;
    cv::Point ellipse_center = ellipse.center;
    float major_axis = ellipse.size.width/2;
    float minor_axis = ellipse.size.height/2;
    cv::Point pixel;
    float a,b,c,d;

    for(int x = 0; x < image.cols; x++)
    {
        for(int y = 0; y < image.rows; y++) 
        {
        auto u =  cos(angle*pi/180)*(x-ellipse_center.x) + sin(angle*pi/180)*(y-ellipse_center.y);
        auto v = -sin(angle*pi/180)*(x-ellipse_center.x) + cos(angle*pi/180)*(y-ellipse_center.y);

        distance = (u/major_axis)*(u/major_axis) + (v/minor_axis)*(v/minor_axis);  

        if(distance<=1)
        {
            image.at<cv::Vec3b>(y,x)[1] = 255;
        }
      }
  }
  return image;  
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X