Go to the documentation of this file.00001
00002 #include <iostream>
00003 #include <ros/ros.h>
00004 #include <sensor_msgs/Image.h>
00005 #include <ros/package.h>
00006 #include <nodelet/nodelet.h>
00007 #include <cv_bridge/cv_bridge.h>
00008 #include <opencv2/core/core.hpp>
00009 #include <opencv2/imgproc/imgproc.hpp>
00010 #include <dynamic_reconfigure/server.h>
00011 #include <sensor_msgs/image_encodings.h>
00012 #include <pluginlib/class_list_macros.h>
00013 #include <image_transport/image_transport.h>
00014 #include <opencv2/core/core.hpp>
00015 #include <opencv2/highgui/highgui.hpp>
00016 #include "Camera.h"
00017 #include "CameraContext.h"
00018 #include "CameraException.h"
00019
00020
00021
00022 #include "omnicamera_msgs/GetLadybugCameraConfig.h"
00023 #include "omnicamera_msgs/GetVirtualCameraConfig.h"
00024 #include "omnicamera_msgs/VirtualCameraConfig.h"
00025 #include "omnicamera_msgs/LadybugCameraConfig.h"
00026
00027
00028
00029 #define ARRAY_LENGTH 30
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 namespace omnicamera{
00040 class ColourCorrection : public nodelet::Nodelet{
00041
00042
00043 public:
00044 ColourCorrection(){
00045 }
00046
00047 private:
00048 ros::NodeHandle n;
00049 boost::shared_ptr<image_transport::ImageTransport> it;
00050 image_transport::Publisher cameraPub;
00051 image_transport::Subscriber sub;
00052 int iter;
00053 bool full;
00054 float b_list [ARRAY_LENGTH];
00055 float g_list [ARRAY_LENGTH];
00056 float r_list [ARRAY_LENGTH];
00057 double vertical_startposition;
00058 double vertical_endposition;
00059 double horizontal_startposition;
00060 double horizontal_endposition;
00061 int SATURATION_VAL1;
00062 int SATURATION_VAL2;
00063
00064 double corb;
00065 double corg;
00066 double corr;
00067
00068
00069
00070
00071 void onInit(){
00072
00073 NODELET_INFO("Starting image correction");
00074 ros::NodeHandle &n = getNodeHandle();
00075 it.reset(new image_transport::ImageTransport(n));
00076 sub = it->subscribe("in", 1, &ColourCorrection::correct_col, this);
00077 cameraPub = it->advertise("out", 1);
00078
00079
00080 iter=-1;
00081 full=false;
00082
00083
00084
00085 n.param("vertical_startposition", vertical_startposition, 0.5);
00086 n.param("vertical_endposition", vertical_endposition, 0.65);
00087 n.param("horizontal_startposition", horizontal_startposition, 0.94);
00088 n.param("horizontal_endposition", horizontal_endposition, 1.0);
00089 n.param("saturation_value1",SATURATION_VAL1,250);
00090 n.param("saturation_value2",SATURATION_VAL2,200);
00091
00092
00093 n.param("cor_b",corb,1.07);
00094 n.param("cor_g",corg,1.0);
00095 n.param("cor_r",corr,0.95);
00096
00097
00098
00099 }
00100
00101
00102
00103
00104 cv::Vec3i getMeanColour(cv::Mat* im,bool sat_ign){
00105 cv::Vec3i mean_col;
00106 cv::Vec3i col;
00107
00108 int rows=im->rows;
00109 int cols=im->cols;
00110
00111
00112
00113 int S=0;
00114 for (int i=0;i<3;i++){
00115 mean_col(i)=0;
00116 }
00117 for(int i=vertical_startposition*rows;i<vertical_endposition*rows;i++){
00118 for(int j=horizontal_startposition*cols;j<horizontal_endposition*cols;j++){
00119 col =(*im).at<cv::Vec3b>(i,j);
00120 if ( col(1)<253 && col(2)<253 && col(3)<253){
00121 mean_col=mean_col+col;
00122 S++;
00123 }
00124 }
00125 }
00126 mean_col=mean_col/S;
00127 return mean_col;
00128
00129 }
00130
00131
00132 void linear_correction(float b_c, float g_c,float r_c,cv::Mat* im){
00133 int i,j;
00134 float cors [3] ={b_c,g_c,r_c};
00135 int temp;
00136 bool sat=false;
00137 for (i=0;i<(*im).rows;i++){
00138 for(j=0;j<(*im).cols;j++){
00139 sat=false;
00140 cv::Vec3b* a =(*im).ptr<cv::Vec3b>(i,j);
00141
00142 for (int k=0;k<3;k++){
00143 if((*a)(k)>(uchar)SATURATION_VAL1)
00144 sat=true;
00145 }
00146 if (sat){
00147 for(int k=0;k<3;k++){
00148 if((*a)(k)<(uchar)SATURATION_VAL2){
00149 sat=false;
00150 }
00151 }
00152 }
00153
00154 if (!sat){
00155 for (int k=0;k<3;k++){
00156
00157 temp=(*a)(k)*cors[k];
00158 if(temp<255){
00159 (*a)(k)= (uchar) temp;
00160 }
00161 else {
00162 (*a)(k)=(uchar)255;
00163 }
00164
00165 }
00166 }
00167
00168 }
00169
00170
00171 }
00172
00173
00174 }
00175
00176 void correct_col(const sensor_msgs::ImageConstPtr& msg){
00177
00178 cv_bridge::CvImagePtr cv_msg;
00179 cv::Mat* im;
00180 cv_msg= cv_bridge::toCvCopy( msg, std::string());
00181 im=&(cv_msg->image);
00182
00183 if ((*im).empty()){
00184 ROS_INFO("No Image for colour correction");
00185 }
00186 else {
00187
00188
00189 cv::Vec3i mean_col=getMeanColour(im,true);
00190 uint grey_col = ((uint)mean_col(0)+(uint)mean_col(1)+(uint)mean_col(2)) /3;
00191
00192
00193 float b_c= grey_col*corb/(mean_col(0));
00194 float g_c= grey_col*corg/(mean_col(1));
00195 float r_c= grey_col*corr/(mean_col(2));
00196
00197
00198
00199 iter++;
00200 if (iter==ARRAY_LENGTH){
00201 iter=0;
00202 full=true;
00203 }
00204 b_list[iter]=b_c;
00205 g_list[iter]=g_c;
00206 r_list[iter]=r_c;
00207 b_c=0;
00208 g_c=0;
00209 r_c=0;
00210 int list_end;
00211 if(full){
00212 list_end=ARRAY_LENGTH;
00213 }
00214 else{
00215 list_end=iter+1;
00216 }
00217 for(int i=0;i<list_end;i++){
00218 b_c+=b_list[i];
00219 g_c+=g_list[i];
00220 r_c+=r_list[i];
00221 }
00222 b_c=b_c/list_end;
00223 g_c=g_c/list_end;
00224 r_c=r_c/list_end;
00225
00226 linear_correction(b_c,g_c,r_c,im);
00227
00228
00229
00230 this->cameraPub.publish(cv_msg->toImageMsg());
00231
00232 }
00233 }
00234
00235 };
00236 }
00237
00238 PLUGINLIB_DECLARE_CLASS(omnicamera,bag_colour_correction, omnicamera::ColourCorrection, nodelet::Nodelet)
00239
00240
00241
00242