Using cvGetSize and cvSplit
I'm trying to find centroids of four green circles in image_transport video. I'm planning to convert to OpenCV image with cv_bridge. Then, with OpenCV, extract green channel (with cv::Split) and apply a threshold.
For this I need cvCreateImage, cvGetSize and cvSplit, like this:
cv_ptr = cv_bridge::toCvCopy(original_image, enc::BGR8); this works
cv_ptr_red = cvCreateImage( cvGetSize(cv_ptr), 8, 1); this does not work
cv_ptr_green = cvCreateImage( cvGetSize(cv_ptr), 8, 1); this does not work
cv_ptr_blue = cvCreateImage( cvGetSize(cv_ptr), 8, 1); this does not work
These lines that doesn't work give me the following error:
cannot convert ‘cv_bridge::CvImage’ to ‘const CvArr* {aka const void*}’ for argument ‘1’ to ‘CvSize cvGetSize(const CvArr*)’
What am I missing?
Update on error
I'm sorry for so many basic questions, but this C++ is way more complicated then Matlab.
It does compile using the cv_ptr_green->image but the it gives me an error when running it. I reduced the code to try to find out where it was happening and now my code only has:
cv_bridge::CvImagePtr cv_ptr_green;
cv_ptr = cv_bridge::toCvCopy(original_image, enc::BGR8);
cv_ptr_green->image.create(cv_ptr->image.size(), CV_8UC1);
And the error I get when running (compiling is OK):
ardrone_visualservo: /usr/include/boost/smart_ptr/shared_ptr.hpp:418: T* boost::shared_ptr<t>::operator->() const [with T = cv_bridge::CvImage]: Assertion `px != 0' failed.
Aborted (core dumped)
If I understood what it tried to say, it's complaining about the -> operator usage with cv_bridge::CvImage (which is the type of my cv_ptr_green object).
Any ideas how to fix this?
Updating using alternative function cv::mixChannels
I found that maybe I can use cv::mixChannels() to extract only the green channel (as I actually need) with
// cv_ptr[1] -> cv_ptr_green[1]
int from_to[] = {1,1};
cv::mixChannels( cv_ptr, 1, cv_ptr_green, 1, from_to, 1);
but it also gives me an error
path/to/cpp/file.cpp: In function ‘void imageCallback(const ImageConstPtr&)’:
path/to/cpp/file.cpp:62:58: error: no matching function for call to ‘mixChannels(cv_bridge::CvImagePtr&, int, cv_bridge::CvImagePtr&, int, int [2], int)’
path/to/cpp/file.cpp:62:58: note: candidates are: /opt/ros/fuerte/include/opencv2/core/core.hpp:2137:17: note: void cv::mixChannels(const cv::Mat, size_t, cv::Mat, size_t, const int*, size_t)
/opt/ros/fuerte/include/opencv2/core/core.hpp:2137:17: note: no known conversion for argument 1 from ‘cv_bridge::CvImagePtr {aka boost::shared_ptr<cv_bridge::cvimage>}’ to ‘const cv::Mat*’
/opt/ros/fuerte/include/opencv2/core/core.hpp:2139:17: note: void cv::mixChannels(const std::vector<cv::mat>&, std::vector<cv::mat>&, const int*, size_t)
/opt/ros/fuerte/include/opencv2/core/core.hpp:2139:17: note: candidate expects 4 arguments, 6 provided
/opt/ros/fuerte/include/opencv2/core/core.hpp:2141:19: note: void cv::mixChannels(cv::InputArrayOfArrays, cv::InputArrayOfArrays, const std::vector<int>&)
Complete code
#include <ros/ros.h>
//Use image_transport for publishing and subscribing to images in ROS
#include <image_transport/image_transport.h>
//Use cv_bridge to convert between ROS and OpenCV Image formats
#include <cv_bridge ...
Are you still using the older version of openCV? In that case are your dependencies also set to that version?
What do you mean by older version of openCV? I installed everything, both ROS and openCV, about four days ago. My includes are: #include <opencv2/opencv.hpp>,
include <opencv2/imgproc/imgproc.hpp> and #include <opencv2/highgui/highgui.hpp>. openCV version is stock version that came with ROS.
SivamPillai, thank you very much for your help. Unfortunately, it did not work for me though. It seems it can't find cv:create and cv:size member functions. Yes, I believe my OpenCV is the new one which creates cv:Mat types form cv_bridge (I had this include, but it was not listed previously).
I will add more of the code and maybe it makes it easier to help me.
The error I get with your suggestions is: ‘cv_bridge::CvImagePtr’ has no member named ‘create’, ‘size’ is not a member of ‘cv’ and suggested alternative: /usr/include/boost/mpl/size_fwd.hpp:20:38: note: ‘boost::mpl::size’
I missed to realize that you created all the images using cv_bridge... In that case you will always have to use the structure member image (cv_ptr->image). The proper use of size is as a member of the class... I assume the change now should work... sorry for the previous mistake. (answer is updated)
SivamPillai, thanks again for the help. As you can see, I'm not used to C++ programming and it is far more difficult than Matlab. :/ Could you please take a look at the "Update on error" I added to the question?
That's a common error and it is related to your image not being properly initialized and pointing to NULL. http://answers.ros.org/question/11430/sending-the-image-using-cvbridge/ this link maybe of some help. Try to initialize your image before using it.