00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <ros/ros.h>
00030 #include <stdio.h>
00031 #include <iostream>
00032 #include "std_msgs/String.h"
00033 #include <image_transport/image_transport.h>
00034 #include <cv_bridge/cv_bridge.h>
00035 #include <sensor_msgs/image_encodings.h>
00036 #include <opencv2/imgproc/imgproc.hpp>
00037 #include <opencv2/highgui/highgui.hpp>
00038 #include <opencv/cv.h>
00039 #include <opencv/highgui.h>
00040 #include <cv_bridge/CvBridge.h>
00041 #include <cvaux.h>
00042 #include <math.h>
00043 #include <cxcore.h>
00044 #include <geometry_msgs/Twist.h>
00045 #include "boost/thread/mutex.hpp"
00046 #include "boost/thread/thread.hpp"
00047
00048
00049
00050 using namespace std;
00051 using namespace cv;
00052 namespace enc = sensor_msgs::image_encodings;
00053 static const char WINDOW[] = "Image window";
00054
00055 float prevVelocity_angular, prevVelocity_linear, newVelocity_angular,
00056 newVelocity_linear;
00057 float derive_angular, derive_linear, dt = 0.5;
00058 float horizontalcount;
00059
00060 class ImageConverter {
00061 ros::NodeHandle nh_, ph_;
00062 ros::NodeHandle n;
00063 ros::Publisher pub;
00064 ros::Publisher tog;
00065 image_transport::ImageTransport it_;
00066 image_transport::Subscriber image_sub_;
00067 image_transport::Publisher image_pub_;
00068 std_msgs::String msg;
00069
00070 double linear_, angular_;
00071 double l_scale_, a_scale_;
00072 double left_threshold, right_threshold;
00073 public:
00074 ImageConverter() :
00075 linear_(0.05),
00076 angular_(0.05),
00077 l_scale_(1.0),
00078 a_scale_(1.0),
00079 left_threshold(150),
00080 right_threshold(450),
00081 it_(nh_) {
00082 pub = n.advertise <geometry_msgs::Twist> ("cmd_vel", 1);
00083 image_sub_ = it_.subscribe("/usb_cam/image_raw", 1,
00084 &ImageConverter::imageCb, this);
00085 image_pub_ = it_.advertise("/arcv/Image", 1);
00086
00087
00088 nh_.param("scale_angular", a_scale_, a_scale_);
00089 nh_.param("scale_linear", l_scale_, l_scale_);
00090 nh_.param("angular", angular_, angular_);
00091 nh_.param("linear", linear_, linear_);
00092 nh_.param("left_threshold", left_threshold, left_threshold);
00093 nh_.param("right_threshold", right_threshold, right_threshold);
00094
00095 }
00096
00097 ~ImageConverter() {
00098 cv::destroyWindow(WINDOW);
00099 }
00100
00101 void imageCb(const sensor_msgs::ImageConstPtr& msg) {
00102
00103 sensor_msgs::CvBridge bridge;
00104 IplImage* img = bridge.imgMsgToCv(msg, "rgb8");
00105 geometry_msgs::Twist velMsg;
00106 CvMemStorage* storage = cvCreateMemStorage(0);
00107 CvSeq* lines = 0;
00108 int i, c, d;
00109 float c1[50];
00110 float m, angle;
00111 float buf;
00112 float m1;
00113 float dis;
00114 int k = 0, k1 = 0;
00115 int count = 0;
00116
00117 float xv;
00118 float yv;
00119 int vc = 0;
00120 float xvan = 0, yvan = 0;
00121 static float xvan1 = 0, yvan1 = 0;
00122 float num = 0;
00123 static float count1 = 0;
00124 float dv;
00125 float vxx, vyy;
00126
00127 cvSetImageROI(img, cvRect(0, 0, 640, 480));
00128 IplImage* out1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
00129 IplImage* gray_out = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00130 IplImage* canny_out = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00131 IplImage* gray_out1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
00132 IplImage* canny_out1 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00133 IplImage* canny_out2 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00134
00135 IplImage* gray_out2 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00136
00137 cvSmooth(img, out1, CV_GAUSSIAN, 11, 11);
00138
00139 cvCvtColor(out1, gray_out, CV_RGB2GRAY);
00140 cvNot(gray_out,gray_out2);
00141 cvCanny(gray_out2, canny_out, 80, 125, 3);
00142 cvCvtColor(canny_out, gray_out1, CV_GRAY2BGR);
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 lines = cvHoughLines2(canny_out, storage, CV_HOUGH_PROBABILISTIC, 1,
00163 CV_PI / 180, 80, 50, 10);
00164 for (i = 0; i < lines->total; i++) {
00165
00166 CvPoint* line = (CvPoint*) cvGetSeqElem(lines, i);
00167 {
00168 {
00169 cvLine(out1, line[0], line[1], CV_RGB(0, 255, 0), 1, 8);
00170 cvLine(gray_out1, line[0], line[1], CV_RGB(0, 255, 0), 2,
00171 8);
00172 xv = line[0].x - line[1].x;
00173 yv = line[0].y - line[1].y;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 angle = atan2(xv, yv) * 180 / 3.14159265;
00197
00198
00199 buf = (line[0].x + line[1].x) / 2;
00200 printf("line[0].x: %f", line[0].x);
00201 printf("line[1].x: %f", line[1].x);
00202 velMsg.linear.z = buf;
00203 velMsg.linear.y = angle;
00204
00205 if (abs(buf) <= left_threshold) {
00206 velMsg.angular.z = angular_ * a_scale_;
00207 }
00208 else if (abs(buf) >= right_threshold) {
00209 velMsg.angular.z = -angular_ * a_scale_;
00210 }
00211 else {
00212 velMsg.linear.x = linear_ * l_scale_;
00213 }
00214
00215
00216 printf("\nX::Y::X1::Y1::%d:%d:%d:%d", line[0].x, line[0].y,
00217 line[1].x, line[1].y);
00218
00219 pub.publish(velMsg);
00220
00221 }
00222
00223 }
00224
00225 cvSeqRemove(lines, i);
00226
00227 }
00228 cvShowImage("OUT1", out1);
00229 cvShowImage("GRAY_OUT1", gray_out1);
00230
00231
00232
00233
00234
00235
00236
00237 cv::waitKey(3);
00238 sensor_msgs::ImagePtr out = sensor_msgs::CvBridge::cvToImgMsg(img,
00239 "rgb8");
00240 image_pub_.publish(out);
00241 cvClearMemStorage(storage);
00242 cvReleaseMemStorage(&storage);
00243 cvReleaseImage( &out1 );
00244 cvReleaseImage( &gray_out );
00245 cvReleaseImage( &canny_out );
00246 cvReleaseImage( &gray_out1 );
00247 cvReleaseImage( &canny_out1 );
00248 cvReleaseImage( &canny_out2 );
00249 cvReleaseImage( &gray_out2 );
00250
00251
00252
00253 }
00254
00255 };
00256
00257 int main(int argc, char** argv) {
00258 ros::init(argc, argv, "image_converter");
00259 ImageConverter ic;
00260 ros::spin();
00261 return 0;
00262 }