Quantcast
Channel: OpenCV Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 41027

Count number of colored objects in image

$
0
0
*********************** **EDIT-1** ************************ Sorry for the delayed response. Being new to OpenCV I did some research and found out that a connected components function was introduced in OpenCV 3.0 and it is only available in C++ (AFAIK) as shown [here](http://docs.opencv.org/3.0-beta/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=connectedcomponents#connectedcomponents). So, I decided to to write my code in C++. I have also updated the test image (I would like to make it work on this before I got to video stream). Here is my code: #include #include #include #include using namespace std; cv::Mat connect_components(cv::Mat img, int threshval) { cv::Mat bw = threshval < 128 ? (img < threshval) : (img > threshval); cv::Mat labelImage(img.size(), CV_8S); auto nLabels = cv::connectedComponents(bw, labelImage, 8); vector colors(nLabels); colors[0] = cv::Vec3b(0, 0, 0); //background for(auto label = 1; label < nLabels; ++label){ colors[label] = cv::Vec3b(255, 255, 255); } cv::Mat dst(img.size(), CV_8UC3); for(auto r = 0; r < dst.rows; ++r){ for(auto c = 0; c < dst.cols; ++c){ auto label = labelImage.at(r, c); cv::Vec3b &pixel = dst.at(r, c); pixel = colors[label]; } } return dst; } int main(int argc, char **argv) { cv::VideoCapture webcam(0); if (!webcam.isOpened()) { cerr << "Cannot open webcam" << endl; exit(-1); } // Define range for blue and red color in HSV const cv::Scalar blue_range[] = { {110, 50, 50}, {130, 255, 255} }; const cv::Scalar red_range[] = { {0, 200, 50}, {10, 255, 150} }; cout << CV_MAJOR_VERSION << ", " << CV_MINOR_VERSION << endl; cv::Mat original_frame, color_mask[2], final_mask; while (true) { try { webcam.read(original_frame); // grab each frame cv::Mat frame_hsv; cv::cvtColor(original_frame, frame_hsv, CV_BGR2HSV); // convert BGR to HSV // threshold HSV image to get only defined range colors cv::inRange(frame_hsv, blue_range[0], blue_range[1], color_mask[0]); cv::inRange(frame_hsv, red_range[0], red_range[1], color_mask[1]); // add the masks final_mask = color_mask[0] + color_mask[1]; // Bitwise-AND full mask and original image cv::Mat colored_boxes; cv::bitwise_and(original_frame, original_frame, colored_boxes, final_mask); // Apply morphological closing cv::Mat morphed_boxes; cv::morphologyEx(colored_boxes, morphed_boxes, cv::MORPH_CLOSE, cv::Mat::ones(10, 10, CV_8UC1)); // Connected componenets auto labeled_boxes = connect_components(colored_boxes, 62); // Display the image //cv::imshow("Webcam", original_frame); cv::imshow("Boxes", morphed_boxes); // quit progrem is user inputs ESC or q auto user_input = (cv::waitKey(5) & 0xFF); if ((user_input == 27) || (user_input == 113)) { break; } } catch (cv::Exception &e) { cout << "Exception caught" << endl; cout << e.what(); break; } } return 0; } The connected_components function is adopted from [here](https://github.com/Itseez/opencv/blob/master/samples/cpp/connected_components.cpp). When I run this, I get the following exception: 3, 0 8UC3 OpenCV Error: Assertion failed (L.channels() == 1 && I.channels() == 1) in connectedComponents_sub1, file /source/opencv-3.0.0/modules/imgproc/src/connectedcomponents.cpp, line 341 Exception caught /source/opencv-3.0.0/modules/imgproc/src/connectedcomponents.cpp:341: error: (-215) L.channels() == 1 && I.channels() == 1 in function connectedComponents_sub1 I think I know why I'm getting this error. According to the [connectComponents documentation](http://docs.opencv.org/3.0-beta/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=connectedcomponents#connectedcomponents), it only supports image types CV_32S and CV_16U. I confirmed this when I changed the line auto nLabels = cv::connectedComponents(bw, labelImage, 8); to auto nLabels = cv::connectedComponents(bw, labelImage, 8, CV_8S); and got the following exception: 3, 0 8UC3 OpenCV Error: Unsupported format or combination of formats (the type of labels must be 16u or 32s) in connectedComponents, file /source/opencv-3.0.0/modules/imgproc/src/connectedcomponents.cpp, line 377 Exception caught /source/opencv-3.0.0/modules/imgproc/src/connectedcomponents.cpp:377: error: (-210) the type of labels must be 16u or 32s in function connectedComponents The problem is I don't know how to fix this. Is there a work around for this? If you'd like to try the entire code you can download it from my github account [here](https://github.com/sudarshan85/opencv_box_counting/tree/box_id). ********************* **Original Question** ************************ Hi, I am detecting multiple objects of different color from a video stream. I would like to count how many objects of each color appear in the stream. I am using OpenCV 2.4.8 on Ubuntu 14.04. Here is the code: #!/usr/bin/env python import cv2 import numpy as np cap = cv2.VideoCapture(0) while(1): # Take each frame _, frame = cap.read() # Convert BGR to HSV hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # define range of blue color in HSV lower_blue = np.array([110,50,50]) upper_blue = np.array([130,255,255]) # define range of red color in HSV lower_red = np.array([160, 100, 100]) upper_red = np.array([179, 255, 255]) # Threshold the HSV image to get only blue colors blue_mask = cv2.inRange(hsv, lower_blue, upper_blue) # Threshold the HSV image to get only red colors red_mask = cv2.inRange(hsv, lower_red, upper_red) # add the masks mask = red_mask + blue_mask # Bitwise-AND mask and original image res = cv2.bitwise_and(frame, frame, mask = mask) # cv2.imshow('frame',frame) # cv2.imshow('mask',mask) cv2.imshow('res',res) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows() Attached is an image from the video stream. In that image there are 4 red boxes and 4 blue boxes which I would like to count. Any help is appreciated. Thanks.[C:\fakepath\image.png](/upfiles/14503718907061841.png)

Viewing all articles
Browse latest Browse all 41027

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>