I am trying to bridge Ros images to OpenCV so i started using cv_bridge and followed this tutorial. http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages
I think I was able to make the CMakeLists.txt file correct and using catkin_make does build the executable and the code runs, however nothing really happens besides the node showing up as a leaf topic when using rqt_graph.
However, i ran into some issues with the line of the tutorial where it says: Run a camera or play a bag file to generate the image stream. Now you can run this node, remapping "in" to the actual image stream topic.
I am using a Kinect for the image source and have installed the openni drivers and can confirm that it is working correctly, as when i run rviz or rtabmap point cloud images is being shown.
I'm guessing the issue is that i am not mapping the publishers and subscribers correctly, as when i am trying to use image_view to see if the camera data is working it returns blank. In the command line, i am typing in: rosrun image_view image_view image:=/camera/rgb/image_color However, I am receiving this error: GLib-GObject-CRITICAL **: 15:13:13.357: g_object_unref: assertion 'G_IS_OBJECT (object)' failed, which i'm assuming is an error with me renaming the topics.
When running rqt_graph with both the openni node and the tutorial file it looks like the this.
https://imgur.com/fLd69WG
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
static const std::string OPENCV_WINDOW = "Image window";
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
image_transport::Publisher image_pub_;
public:
ImageConverter()
: it_(nh_)
{
// Subscrive to input video feed and publish output video feed
//I'm guessing this is where my errors are
image_sub_ = it_.subscribe("/camera/image_raw", 1,
&ImageConverter::imageCb, this);
image_pub_ = it_.advertise("/image_converter/output_video", 1);
cv::namedWindow(OPENCV_WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(OPENCV_WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
// Draw an example circle on the video stream
if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));
// Update GUI Window
cv::imshow(OPENCV_WINDOW, cv_ptr->image);
cv::waitKey(3);
// Output modified video stream
image_pub_.publish(cv_ptr->toImageMsg());
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_converter");
ROS_INFO_STREAM("test to see if node is running");
ImageConverter ic;
ros::spin();
return 0;
}
I have fixed the issue by using rostpic hz [topic] and checking which ones are receiving camera data. From there, I changed the subscriber to image_sub_ = it_.subscribe("camera/rgb/image_color", 1, &ImageConverter::imageCb, this); and it worked
Related
As I am completely new to OpenCV, I tried following a tutorial to capture video from a webcam. I used the following code:
#include "opencv2\opencv.hpp"
#include <stdint.h>
using namespace cv;
using namespace std;
int main(int argv, char** argc) {
Mat frame;
VideoCapture vid(0); //0 if we only have one camera
if (!vid.isOpened()) { //check camera has been initialized
cout << "ERROR: Cannot open the camera";
return -1;
}
while (vid.read(frame)) {
imshow("webcam", frame);
if (waitKey(30) >= 0) break;
}
return 0;
}
When I run the program, a window that shows the video feed opens, but it then almost immediately closes. I get this snippet from the Debug output:
SETUP: Device is setup and ready to capture.
Event: Code: 0x0d Params: 0, 0
Event: Code: 0x0e Params: 0, 0
Exception thrown at 0x000007FEFCBAA06D in test.exe: Microsoft C++ exception: cv::Exception at memory location 0x000000000026EB10.
SETUP: Disconnecting device 0
I don't know what could be wrong with my code or even how to begin debugging this. Any advice? Thank you!
So I have played around in OpenCV a bunch before and never run into this problem. I am implementing a MeanShift algorithm and trying to do it on video devices, images, and videos. Devices and images work; however, no matter what I try, when I run VideoCapture on my filename (whether setting it in the Constructor or using the VideoCapture::open() method, and whether local or with a full path) I always get stuck in my error check.
Thoughts? Ideas? code below. running in Visual Studio 2012
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\core\core.hpp"
#include "opencv2\opencv.hpp"
#include "opencv2\video\video.hpp"
#include <string>
using cv::Mat;
using std::string;
enum Filetype{Image, Video};
int main(int argc, char* argv[])
{
string filename = "short_front.avi";// "C:\\Users\\Jonathan\\Videos\\short_front.mp4"; //"hallways.jpg";
Mat cv_image; //convert to unsigned char * with data
Mat filtImage_;
Mat segmImage_;
Mat whiteImage_;
cv::VideoCapture vid;
vid.open("C:/Users/Jonathan/Desktop/TestMeanShift/TestMeanShift/short_front.avi");
cv::waitKey(1000);
if ( !vid.isOpened() ){
throw "Error when reading vid";
cv::waitKey(0);
return -1;
}
// cv_image = cv::imread(filename);//, CV_LOAD_IMAGE_COLOR);
// if(! cv_image.data){
// std::cerr << "Image Failure: " << std::endl;
// system("pause");
// return -1;
// }
//Mat cv_image_gray;
//cv::cvtColor(cv_image,cv_image_gray,CV_RGB2GRAY);
for (;;)
{
vid >> cv_image;
if ( !cv_image.data)
continue;
cv::imshow("Input",cv_image); //add a normal window here to resizable
}
EDIT: This is a distinct problem from the one listed here because it deals with a specific corner case: VideoCapture and ImageCapture both work, only not VideoCapture with a file. When it doesn't work, the code runs properly, except that the "video" it creates is incomplete as it didn't open properly. Therefore, as the code above does not crash in compile time or run time, the only indicator is bad output (6KB video output file). If you are having issues not with the corner case I am describing but general issues with the above functions in OpenCV, the aforementioned link could help you.
im on Ubuntu 14.04 and I'm trying to write a program that will stream my desktop, using the answer to this: libvlc stream part of screen as an example. However, I don't have another computer readily aviable to see that the stream is going along well, so how can I view that stream on my computer?
libvlc_vlm_add_broadcast(inst, "mybroad", "screen://",
"#transcode{vcodec=h264,vb=800,scale=1,acodec=mpga,ab=128,channels=2,samplerate=44100}:http{mux=ts,dst=:8080/stream}",
5, params, 1, 0)
My program throws no errors, and writes this
[0x7f0118000e18] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[0x7f0118000e18] x264 encoder: profile High, level 3.0
[0x7f0118000e18] x264 encoder: final ratefactor: 25.54
[0x7f0118000e18] x264 encoder: using SAR=1/1
[0x7f0118000e18] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[0x7f0118000e18] x264 encoder: profile High, level 2.2
So to me, everything seems ok. However, I don't know how to view that stream from my computer- if I open vlc and try to open a network stream, using http:// #:7777 (space on purpose, website does not allow to post such links) I get the invalid host error in its log. This probably is a silly mistake or error on my part, but any help would be greatly appreciated!
if anyone needs it, this is my entire code (I'm using QT 4.8.6):
#include <QCoreApplication>
#include <iostream>
#include <vlc/vlc.h>
#include <X11/Xlib.h>
// #include <QDebug>
using namespace std;
bool ended;
void playerEnded(const libvlc_event_t* event, void *ptr);
libvlc_media_list_t * subitems;
libvlc_instance_t * inst;
libvlc_media_player_t *mp;
libvlc_media_t *media;
libvlc_media_t * stream;
int main(int argc, char *argv[])
{
XInitThreads();
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
ended = false;
QCoreApplication a(argc, argv);
// the array with parameters
const char* params[] = {"screen-top=0",
"screen-left=0",
"screen-width=640",
"screen-height=480",
"screen-fps=10"};
// Load the VLC engine */
inst = libvlc_new (0, NULL);
if(!inst)
std::cout << "Can't load video player plugins" << std::endl;
cout<< "add broacast: " <<
libvlc_vlm_add_broadcast(inst, "mybroad",
"screen://",
"#transcode{vcodec=h264,vb=800,scale=1,acodec=mpga,ab=128,channels=2,samplerate=44100}:http{mux=ts,dst=:8080/stream}",
5, params, // <= 5 == sizeof(params) == count of parameters
1, 0)<< '\n';
cout<< "poczatek broacastu: " <<libvlc_vlm_play_media(inst, "mybroad")<< '\n';
media = libvlc_media_new_location(inst,http://#:8080/stream");
// Create a media player playing environment
mp = libvlc_media_player_new (inst);
libvlc_media_player_play (mp);
cout<<"szatan!!!"<<endl;
int e;
cin>>e;
/* Stop playing */
libvlc_media_player_stop (mp);
/* Free the media_player */
libvlc_media_player_release (mp);
libvlc_release (inst);
return a.exec();
}
so, i have found the answer- stack overflow wont let me post an answer because I'm new here, so its in the comments! I should have used my IP address when creating media: media = libvlc_media_new_location(inst, "http: //192.168.1.56:8080");(space on purpose so that forum does not hide link) works great! –
I am trying to display the video feed from IP camera getting the following error
warning: Could not find codec parameters
(../../modules/highgui/src/cap_ffmpeg_impl.hpp:540)
Here's the code for the same.
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int, char**)
{
VideoCapture vcap;
Mat image;
// This works on a D-Link CDS-932L
const string videoStreamAddress = "http://admin:admin123#172.41.20.55:80/? action=stream?dummy=param.mjpg";//From mjpeg streamer
//const string videoStreamAddress = "http://192.168.1.13:8080/videofeed? dummy=param.mjpg"; // Streaming from android using ip-cam
//open the video stream and make sure it's opened
if(!vcap.open(videoStreamAddress)) {
cout << "Error opening video stream or file" << std::endl;
return -1;
}
for(;;) {
if(!vcap.read(image)) {
cout << "No frame" << std::endl;
waitKey();
}
cv::imshow("Output Window", image);
if(cv::waitKey(1) >= 0) break;
}
}
First i got different error so I installed K-Lite codec. Now I am getting this error.
Can some one please tell me what is the error related to.
I have gone through many post from stackoverflow and opencv also but could manage to get a satisfactory answer.
Please help me.
Thanks in advance.
I was able to Solve the problem with the following code.
#include <stdio.h>
#include <opencv2/opencv.hpp>
int main(){
CvCapture *camera=cvCaptureFromFile("http://username:password#ipOfCamera/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=30&.mjpg");
if (camera==NULL)
printf("camera is null\n");
else
printf("camera is not null");
cvNamedWindow("img");
while (cvWaitKey(10)!=atoi("q")){
double t1=(double)cvGetTickCount();
IplImage *img=cvQueryFrame(camera);
/*if(img){
cvSaveImage("C:/opencv.jpg",img);
}*/
double t2=(double)cvGetTickCount();
printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("img",img);
}
cvReleaseCapture(&camera);
}
Would be good if it helps someone like me.
Also Thanks #karlphillip for giving your time.
Warnings are not errors! Relax.
In this case FFmpeg is complaining and not OpenCV. The reason is probably because the mjpg format that is specified on the URL doesn't really require an actual codec.
I'm using ROS and OpenCV in C++ environment in order to acquire a video (gray-scale) from a ROS node, convert the data through cv_bridge (in order to elaborate it through OpenCV), extract some data and publish them on a topic as ROS messages.
My problem is that I don't know how to send the array frame to the main function in order to elaborate it! I cannot elaborate out of it, because I need to distinguish between different data of different frames.
This is my code:
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include "rd_ctrl/proc_data.h"
#include <cv.h>
using namespace std;
namespace enc = sensor_msgs::image_encodings;
rd_ctrl::proc_data points;
ros::Publisher data_pub_;
static const char WINDOW[] = "Image window";
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
image_transport::Publisher image_pub_;
public:
ImageConverter()
: it_(nh_)
{
image_pub_ = it_.advertise("out", 1);
image_sub_ = it_.subscribe("/vrep/visionSensorData", 1, &ImageConverter::imageCb, this);
cv::namedWindow(WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
CvMat frame= cv_ptr->image; //definition of "frame"
cvSmooth(&frame, &frame, CV_MEDIAN);
cvThreshold(&frame, &frame,200, 255,CV_THRESH_BINARY);
cv::imshow(WINDOW, cv_ptr->image);
cv::waitKey(3);
image_pub_.publish(cv_ptr->toImageMsg());
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_proc");
ImageConverter ic;
ros::NodeHandle n;
//....elaboration of "frame" and production of the data "points"
data_pub_.publish(points);
data_pub_ = n.advertise<rd_ctrl::proc_data>("/data_im", 1);
ros::spin();
return 0;
}
I hope that the question is clear enough. Can you help me please?
Now if I understand you correctly you want to call imageCb and have the frame it creates passed back to main. If that is indeed the case then you can modify imageCb as follows:
void imageCb(const sensor_msgs::ImageConstPtr& msg, cv::Mat frame )
You will need to create the frame in main and pass it imageCb:
cv::Mat frame ;
ic.imageCb( ..., frame ) ;
This will use the copy constructor, it will just copy the header and use a pointer to the actual data, so it won't be very expensive.
This previous thread has a much more detailed elaboration on cv::Mat copy constructor.