ROS custom message with sensor_msgs/Image issue with subscriber - ros

I have a custom message -
sensor_msgs/Image im
float32 age
string name
I could successfully write a publisher for this message and it seem to run ok. However, I have an issue with the subscriber.
#include <ros/ros.h>
#include <custom_msg/MyString.h>
#include <custom_msg/MyImage.h>
#include <image_transport/image_transport.h>
#include <sensor_msgs/Image.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>
void custom_image_rcvd( const custom_msg::MyImage& msg )
{
ROS_INFO_STREAM( "msg::: Name:"<< msg.name << " Age:"<< msg.age );
cv::Mat im = cv_bridge::toCvShare( msg.im, "bgr8" )->image ;
cv::imshow("viewz", im );
cv::waitKey(30);
}
int main( int argc, char ** argv )
{
ros::init(argc, argv, "custom_subscriber");
ros::NodeHandle nh;
ros::Subscriber sub2 = nh.subscribe( "custom_image", 2, custom_image_rcvd );
ros::spin();
}
When I try to catkin_make this I get the following error.
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp: In function ‘void custom_image_rcvd(const MyImage&)’:
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: error: no matching function for call to ‘toCvShare(const _im_type&, const char [5])’
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: note: candidates are:
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note: no known conversion for argument 2 from ‘const char [5]’ to ‘const boost::shared_ptr<const void>&’
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note: no known conversion for argument 1 from ‘const _im_type {aka const sensor_msgs::Image_<std::allocator<void> >}’ to ‘const ImageConstPtr& {aka const boost::shared_ptr<const sensor_msgs::Image_<std::allocator<void> > >&}’
make[2]: *** [custom_msg/CMakeFiles/subscribe.dir/subsc.cpp.o] Error 1
make[1]: *** [custom_msg/CMakeFiles/subscribe.dir/all] Error 2
make: *** [all] Error 2
Invoking "make" failed
What I can make out is that msg.im is of the type _im_type aka. sensor_msgs::Image_<ContainerAllocator>. I cannot seem to understand this part.
How can I retrieve my image correctly from this custom message?

You have to take a closer look on the signature of toCvShare. It can be read from the error message, that this function has two overloads:
cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)
and
cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)
So the function either expects an Image plus a pointer to some object (first case) or a ImageConstPtr (second case). You are, however, only passing a Image, so this matches neither of the two options.
If I understand the API documentation correctly, the second argument in the first case is expected to be a pointer to the message that contains the image. Try the following code:
void custom_image_rcvd(const custom_msg::MyImageConstPtr& msg)
{
ROS_INFO_STREAM("msg::: Name:" << msg->name << " Age:" << msg->age);
cv::Mat im = cv_bridge::toCvShare(msg->im, msg, "bgr8")->image;
cv::imshow("viewz", im);
cv::waitKey(30);
}
Note that I changed the call of toCvShare as well as the signature of the callback.

Related

How to push command line arguments into a stack

I'm making a calculator using the command line and am using a stack to push the values of the arguments (digits of the calculator and operators), but I keep getting an invalid conversion from 'char*' to 'std::stack""value_type' and "no matching function for call to 'push(char*&)' error. Any ideas on what im doing wrong?
My code:
#include <iostream>
#include <cmath>
#include <stack>
int main(int argc,char* argv[])
{
std::stack<int> numbers;
// std::stack<char> operators;
for(int i=1;i<argc;++i)
{
numbers.push(argv[i]);
//operators.push(argv[i+1]);
}
while(!numbers.empty())
{
std::cout << numbers.top() << std::endl;
numbers.pop();
// std::cout << operators.top() << std::endl;
// operators.pop();
}
return 0;
I've tried using & and * and $ to try to call the values but I just don't think I'm getting something.

Open video with opencv, string too long error?

I'm trying to open an avi file using openCV:
int main(int argc, char *argv[])
{
const string path = "C:\\Users\\name\\file.avi";
VideoCapture captRefrnc(path);
if (!captRefrnc.isOpened())
{
cout << "Could not open reference " << endl;
return -1;
}
}
However, the output is the following:
[ERROR:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap.cpp (166) cv::VideoCapture::open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.5.4) C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap_images.cpp:235: error: (-5:Bad argument) CAP_IMAGES: error, expected '0?[1-9][du]' pattern, got: h¾∟#± in function 'cv::icvExtractPattern'
[ERROR:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap.cpp (175) cv::VideoCapture::open VIDEOIO(CV_MJPEG): raised C++ exception:
string too long
Could not open reference
I do not understand what this means though? Can openCV just not handle .avi files?

How to set LLVM &AnalysisType::ID For Analysis Pass

I'm trying to create an analysis pass. My code is shown below. I'm using Adrian Sampson approach for building the .so file (https://www.cs.cornell.edu/~asampson/blog/llvm.html).
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "DataDependence.h"
#include "ControlDependence.h"
#include "llvm/IR/Module.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
using namespace llvm;
namespace {
struct SkeletonPass : public ModulePass {
static char ID;
SkeletonPass() : ModulePass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
// AU.addPreserved<AliasAnalysis>();
// AU.setPreservesCFG();
// AU.addRequired<PostDominatorTree>();
}
virtual bool runOnModule(Module &M);
};
bool SkeletonPass::runOnModule(Module &M) {
for (auto mi = M.begin(); mi != M.end(); ++mi) {
if (mi->isDeclaration())
continue;
// MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>(*mi);
PostDominatorTree &PDT = getAnalysis<PostDominatorTree>(*mi); //Error is Here
}
errs() << "Test:\n";
}
}
char SkeletonPass::ID = 0;
static RegisterPass<SkeletonPass> X("SkeletonPass", "Hello World Pass",
false /* Only looks at CFG */,
true /* Analysis Pass */);
The error I'm getting is below
In file included from /usr/local/include/llvm/Pass.h:388:0,
from /media/quentinmayo/storage/Research/LLVM Dev/llvm-pass-skeleton/skeleton/Skeleton.cpp:1:
/usr/local/include/llvm/PassAnalysisSupport.h: In instantiation of ‘AnalysisType& llvm::Pass::getAnalysis(llvm::Function&) [with AnalysisType = llvm::PostDominatorTree]’:
/media/quentinmayo/storage/Research/LLVM Dev/llvm-pass-skeleton/skeleton/Skeleton.cpp:34:71: required from here
/usr/local/include/llvm/PassAnalysisSupport.h:253:38: error: ‘ID’ is not a member of ‘llvm::PostDominatorTree’
return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
^
skeleton/CMakeFiles/SkeletonPass.dir/build.make:62: recipe for target 'skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o' failed
make[2]: *** [skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o] Error 1
CMakeFiles/Makefile2:85: recipe for target 'skeleton/CMakeFiles/SkeletonPass.dir/all' failed
make[1]: *** [skeleton/CMakeFiles/SkeletonPass.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
The error is saying I'm missing AnalysisType::ID. I would like to pass the AliasAnalysis pointer to another class for analysis. I'm confused what this AnalysisType::ID would be? Additionally, can someone explain the relationship between getAnalysisUsage and getAnalysis when creating pass for analysis? Understanding compiler theory doesn't really help me with working with LLVM.
http://llvm.org/docs/doxygen/html/classllvm_1_1Pass.html#ab78af013d3a11515403da8517f8f3d4a
I needed to call the class member getDomTree .
DominatorTree &DI = getAnalysis(*mi).getDomTree();
Advice for others: get friendly with the doxygen pages and reading header files. And if it comes to it, look into the source of your current LLVM build.
Also,AliasAnalysis is now AAResultsWrapperPass.

Aruco tutorial code does not compile

Hello I am getting an error when using aruco. I am just trying to get an example from the tutorial working. I did everything according to the tutorial but I get:
/home/pi/Programs/markerDetection/markerDetection.cpp: In function ‘int main(int, char**)’:
/home/pi/Programs/markerDetection/markerDetection.cpp:26:104: error: invalid initialization of reference of type ‘cv::Ptr<cv::aruco::Dictionary>&’ from expression of type ‘cv::aruco::Dictionary’
aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
^
In file included from /home/pi/Programs/markerDetection/markerDetection.cpp:6:0:
/home/pi/opencv/include/opencv2/aruco.hpp:176:19: note: in passing argument 2 of ‘void cv::aruco::detectMarkers(cv::InputArray, cv::Ptr<cv::aruco::Dictionary>&, cv::OutputArrayOfArrays, cv::OutputArray, const cv::Ptr<cv::aruco::DetectorParameters>&, cv::OutputArrayOfArrays)’
CV_EXPORTS_W void detectMarkers(InputArray image, Ptr<Dictionary> &dictionary, OutputArrayOfArrays corners,
^
CMakeFiles/marker.dir/build.make:54: recipe for target 'CMakeFiles/marker.dir/markerDetection.cpp.o' failed
make[2]: *** [CMakeFiles/marker.dir/markerDetection.cpp.o] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/marker.dir/all' failed
make[1]: *** [CMakeFiles/marker.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
My code is:
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/aruco.hpp"
#include <vector>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
VideoCapture cap;
if(!cap.open(0)){
return 0;
}
for(;;){
Mat inputImage;
cap >> inputImage;
vector< int > markerIds;
vector< vector<Point2f> > markerCorners, rejectedCandidates;
aruco::DetectorParameters parameters;
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
Mat outputImage;
aruco::drawDetectedMarkers(outputImage, markerCorners, markerIds);
if(inputImage.empty()) break;
imshow("Webcam", outputImage);
if(waitKey(1) >= 0) break;
}
return 0;
}
I know there are too many includes and the code needs some work but I just need it to compile and I have no idea what is happening there. Has the function changed?
The following code works for me:
Dictionary declaration:
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
As the function getPredefinedDictionary returns a Ptr<Dictionary>
(http://docs.opencv.org/trunk/d9/d6a/group__aruco.html)
To detect markers:
cv::aruco::detectMarkers(gray, dictionary, marker_corners, marker_ids);
I had the same problem as you. Here is what did the trick:
instead of:
aruco::DetectorParameters parameters;
aruco::Dictionary dictionary=aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
use:
cv::Ptr<aruco::DetectorParameters> parameters;
cv::Ptr<aruco::Dictionary> dictionary=aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
I hope it helps you.
I was missing some include files. These are the ones I have now:
#include "opencv2/aruco.hpp"
#include <iostream>
#include <stdio.h>
#include <opencv2/highgui.hpp>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/videoio/videoio.hpp"
#include <vector>
And the libraries are (these are included in Project-> Properties->settings->Linker->Input ):
opencv_core450.lib
opencv_highgui450.lib
opencv_objdetect450.lib
opencv_videoio450.lib
opencv_imgproc450.lib
opencv_imgcodecs450.lib
opencv_aruco450.lib
opencv_core450d.lib
opencv_highgui450d.lib
opencv_objdetect450d.lib
opencv_videoio450d.lib
opencv_imgproc450d.lib
opencv_imgcodecs450d.lib
opencv_aruco450d.lib
The opencv_aruco450.lib was not getting properly saved as far as I know. This was my problem.

OPEN CV Program execution error?

I am running my below code in eclipse, i have include the path and libraries successfuly, but when run the code it shows an error.
#include <cv.h>
#include<stdio.h>
#include <highgui.h>
//using namespace cv;
int main()
{
Mat image;
image = imread( argv[1], 1 );
if( argc != 2 || !image.data )
{
printf( "No image data \n" );
return -1;
}
namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
imshow( "Display Image", image );
waitKey(0);
printf("this is open cv programming");
return 0;
}
Your main() signature is incomplete
try
int main(int argc, char* argv[])
these parameters represent:
argc // an int indicating the number of arguments passed in to the function
argv[] // an array of character strings, the actual arguments.
The first argument argv[0] is the program name ... so argc is always a minimum of 1.
The second argument, argv[1] will be the first argument your user passes in, bringing argc up to 2. That is what your program is expecting, a single argument from the user, argc == 2.
Try to use the latest version of OpenCV i.e. 2.4.3....however right now you can try to link the debug libraries e.g. opencv_core2.4.xd and run the program to get the Mat image format working.
what is the version of opencv you are using?
try the following code and test...get some picture and run it....
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
Mat im = imread("C:\\some_picture.jpg");
if(im.empty())
return -1;
imshow("TEST",im);
waitKey();
return 0;
}

Resources