0
votes

Comment obtenir la valeur pixelle de l'image contournée avec masque?

J'ai essayé d'extraire des valeurs de pixels moyens (R, G, B) de l'image profilée. Cependant, mon problème est lorsque j'ai appliqué le code ci-dessous, quelque chose d'étranges valeurs ont été observées.

int main(){
cv::Mat star = imread("C:\\Users\\PC\\Desktop\\star\\starcircle.png");
cv::Mat mask = cv::Mat::zeros(star.rows, star.cols, CV_8UC1);
cv::Mat frame;
double b, g, r = 0.0;

cv::imshow("Original", star);

cv::cvtColor(star, frame, CV_BGR2HSV);

cv::inRange(frame, cv::Scalar(29, 220, 220), cv::Scalar(30, 255, 255), mask);

cv::imshow("mask", mask);

cv::Mat result = cv::Mat(star.rows, star.cols, CV_8UC1, star.type());
result.setTo(cv::Scalar(0, 0, 0));

star.copyTo(result, mask);  

int hei = star.rows;
int wid = star.cols;

int corow = hei * wid;

double b, g, r = 0.0;

for (int x = 0; x < hei; x++) {
    for (int y = 0; y < wid; y++) {
        if (mask.at<unsigned char>(x, y) > 0) {
            b += result.at<Vec3b>(x, y)[0];
            g += result.at<Vec3b>(x, y)[1];
            r += result.at<Vec3b>(x, y)[2];

        }
        else {

        }


    }
}

cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
cout << "avg_R: " << r / corow << " \n"; // red value
cout << "avg_G: " << g / corow << " \n"; // green value
cout << "avg_B: " << b / corow << " \n\n"; // blue value


0 commentaires

3 Réponses :


-1
votes
  1. Lire à propos de CV :: mat :: At < / a>: première rangée, deuxième col. Pas (x, y)!

  2. vous voir sur CV :: moyenne : il peut fonctionner avec un masque.

  3. Right Initialisation: double b = 0,0, g = 0,0, r = 0,0;

  4. int CorOow = 0; Et inside boucle ++ corow si masque> 0.


1 commentaires

D'accord. Mais il faut renommer x -> y et y -> x. Les noms variables doivent être clairs du contexte.



2
votes

Quelques choses:

  • Les noms de vos variables et tapis sont au moins déroutant. Utilisez des noms appropriés pour les variables et utilisez mat_ dans la mesure du possible (je dirais toujours).
  • Pour obtenir la moyenne, vous devriez diviser par le nombre de pixels dans le masque, pas par nombre total de pixels.
  • Vous devriez envisager d'utiliser CV :: moyenne
  • Vous avez besoin CV :: WaitKey () Pour voir votre CV :: Imshow

    vérifier le code: xxx


7 commentaires

CV :: WaitKey () op sait à ce sujet parce que OP a affiché les captures d'écran.


@BahramDunadil Merci, mais 1) Ce n'est pas le point principal de la réponse, et 2) dans l'un de ses extraits, l'OP ne l'utilisait pas. Il n'y a pas de mal à le répéter une fois de plus;)


Pouvez-vous expliquer ce qui est si (vrai) lequel dans ce cas, la clause ele sera jamais exécutée?


@Bahramdunadil afin que l'OP puisse tester les deux approches simplement en passant à la modification de si (faux)


Il sera donc préférable de laisser un commentaire sur la ligne pour être clair pour les lecteurs, sinon, c'est déroutant. Merci!


Bonjour, Miki j'apprécie vraiment votre réponse et cela fonctionne bien, mais parfois j'ai un message d'erreur lorsque j'ai changé le fichier image comme ci-dessous. Et cela me donne toujours une valeur peu étrange (le jaune doit être une valeur r et g élevée, mais j'ai toujours une faible valeur sur R et G). Lorsque j'ai vérifié ces valeurs avec la table RGB et j'ai eu une couleur violette. Avez-vous une idée de comment le réparer s'il vous plaît? Processus terminé avec code de sortie -1073741819 (0xc0000005) Savez-vous quel genre de problème est?


@My mauvais ... il y avait un conflit entre le R pour le rouge et le r pour itérer sur des lignes ... maintenant ça devrait aller bien



1
votes

Je vois plusieurs erreurs dans votre code:

 cv::Scalar summed = cv::sum(result); 
 cv::Scalar mean = summed / static_cast<double>(cv::countNonZero(mask));
 std::cout << "$$ Red(R), Green(G), Blue(B) $$" << std::endl << std::endl;
 std::cout << "avg_R: " << mean[2] << std::endl; // red value
 std::cout << "avg_G: " << mean[1] << std::endl; // green value
 std::cout << "avg_B: " << mean[0] << std::endl << std::endl; // blue value


1 commentaires

Omg c'est ce que je voulais exactement. J'apprécie vraiment votre réponse. Merci beaucoup!!