2016-03-07 1 views
0

Je traite des images vidéo et je voudrais détecter si la vidéo contient des pixels d'une certaine gamme de rouge. Est-ce possible?OpenCV: comment interpréter les résultats de inRange?

Voici le code que je suis adaptais d'un tutoriel:

#ifdef __cplusplus 
- (void)processImage:(Mat&)image; 
{ 
    cv::Mat orig_image = image.clone(); 
    cv::medianBlur(image, image, 3); 
    cv::Mat hsv_image; 
    cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV); 
    cv::Mat lower_red_hue_range; 
    cv::Mat upper_red_hue_range; 
    cv::inRange(hsv_image, cv::Scalar(0, 100, 100), cv::Scalar(10, 255, 255), lower_red_hue_range); 
    cv::inRange(hsv_image, cv::Scalar(160, 100, 100), cv::Scalar(179, 255, 255), upper_red_hue_range); 
    // Interpret values here 
} 

valeurs Interprétariat

Je voudrais détecter si les résultats des opérations InRange sont nulles ou non. En d'autres termes, je veux comprendre s'il y a des pixels correspondants dans l'image originale avec une couleur inRange de l'échelle rouge inférieure et supérieure donnée. Comment puis-je interpréter les résultats?

+0

Vous devez d'abord OU le masque inférieur et supérieur. Ensuite, vous pouvez 'countNonZero' pour voir s'il y a des pixels non nuls (c'est-à-dire que vous avez trouvé quelque chose). Il pourrait être préférable d'appliquer d'abord l'érosion morphologique ou l'ouverture pour éliminer les petites tâches (probablement bruyantes), ou trouver des composants connexes ('findContours',' connectedComponentsWithStats') et élaguer/rechercher selon certains critères. – Miki

+0

Merci. Je sais que c'est boiteux mais pourriez-vous s'il vous plaît être en mesure d'ajouter un exemple de code? C'est mon tout premier projet de test OpenCV et j'ai du mal à me familiariser avec toutes ces fonctions et concepts en si peu de temps. – mm24

+0

J'ai posté une réponse. Cela devrait vous aider à démarrer. Si vous avez des exigences plus précises, veuillez les ajouter à votre question et j'essaierai d'apporter une réponse plus précise. – Miki

Répondre

0

Vous devez d'abord OU le masque inférieur et supérieur:

Mat mask = lower_red_hue_range | upper_red_hue_range; 

Ensuite, vous pouvez countNonZero pour voir s'il y a des pixels non nuls (à savoir que vous avez trouvé quelque chose).

int number_of_non_zero_pixels = countNonZero(mask); 

Il pourrait être préférable d'appliquer d'abord l'érosion morphologique ou de l'ouverture pour enlever les petites (probablement bruyants) blobs:

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3)); 
morphologyEx(mask, mask, MORPH_OPEN, kernel); // or MORPH_ERODE 

ou trouver des composants connectés (findContours, connectedComponentsWithStats) et pruneau/recherche selon certains critères:

vector<vector<Point>> contours 
findContours(mask.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

double threshold_on_area = 100.0; 
for(int i=0; i<contours.size(); ++i) 
{ 
    double area = countourArea(contours[i]); 
    if(area < threshold_on_area) 
    { 
     // don't consider this contour 
     continue; 
    } 
    else 
    { 
     // do something (e.g. drawing a bounding box around the contour) 
     Rect box = boundingRect(contours[i]); 
     rectangle(hsv_image, box, Scalar(0, 255, 255)); 
    } 
}