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
00030
00031
00032
00033 #include <ros/ros.h>
00034 #include <opencv/cvwimage.h>
00035 #include <opencv/highgui.h>
00036 #include <opencv/cv.h>
00037
00038 #include <vector>
00039 #include <fstream>
00040
00041 #define nWidth 1280
00042 #define nHeight 960
00043 #define board_w 3
00044 #define board_h 4
00045 #define FOREGROUND 255
00046 #define BACKGROUND 0
00047
00048 using namespace std;
00049
00050 bool integralImageThresholding (IplImage * src, IplImage * img_threshold, double t);
00051
00052 bool integralImageThresholding (IplImage * src, IplImage * img_threshold, double t)
00053 {
00054
00055 if (src == NULL || src->width != img_threshold->width || src->height != img_threshold->height)
00056 return false;
00057
00058
00059 int w = src->width;
00060 int h = src->height;
00061 int s = w / 8;
00062 int sum, num;
00063 int x1, y1, x2, y2;
00064 vector < vector < int > >integral;
00065
00066
00067 integral.resize (h);
00068 for (int i = 0; i < h; i++)
00069 integral[i].resize (w);
00070
00071
00072 for (int i = 0; i < h; i++)
00073 {
00074 sum = 0;
00075 uchar *ptr = (uchar *) (src->imageData + src->widthStep * i);
00076 for (int j = 0; j < w; j++)
00077 {
00078 sum += ptr[j];
00079 if (0 == i)
00080 integral[i][j] = sum;
00081 else
00082 integral[i][j] = integral[i - 1][j] + sum;
00083 }
00084 }
00085
00086
00087 for (int i = 0; i < h; i++)
00088 {
00089 uchar *ptr = (uchar *) (src->imageData + src->widthStep * i);
00090 uchar *out = (uchar *) (img_threshold->imageData + img_threshold->widthStep * i);
00091 for (int j = 0; j < w; j++)
00092 {
00093 x1 = j - s / 2;
00094 x2 = j + s / 2;
00095 y1 = i - s / 2;
00096 y2 = i + s / 2;
00097
00098
00099 if (x1 < 0)
00100 x1 = 0;
00101 if (x2 >= w)
00102 x2 = w - 1;
00103 if (y1 < 0)
00104 y1 = 0;
00105 if (y2 >= h)
00106 y2 = h - 1;
00107
00108 num = (x2 - x1) * (y2 - y1);
00109
00110
00111 if (0 == x1 && y1 != 0)
00112 sum = integral[y2][x2] - integral[y1 - 1][x2];
00113 else if (0 == y1 && x1 != 0)
00114 sum = integral[y2][x2] - integral[y2][x1 - 1];
00115 else if (0 == x1 && 0 == y1)
00116 sum = integral[y2][x2];
00117 else
00118 sum = integral[y2][x2] - integral[y2][x1 - 1] - integral[y1 - 1][x2] + integral[y1 - 1][x1 - 1];
00119
00120
00121 if ((int) (ptr[j]) * num <= sum * (1 - t))
00122 out[j] = FOREGROUND;
00123 else
00124 out[j] = BACKGROUND;
00125 }
00126 }
00127 return true;
00128 }
00129
00130
00131 int main (int argc, char **argv)
00132 {
00133 char *filename = argv[1];
00134 int r_t = atoi (argv[2]);
00135 int bg_t = atoi (argv[3]);
00136 int bg_diff = atoi (argv[4]);
00137
00138 IplImage *image = cvLoadImage (filename, CV_LOAD_IMAGE_COLOR);
00139 IplImage *raw_image = cvCreateImage (cvSize (nWidth, nHeight), 8, 3);
00140 cvCopy (image, raw_image, NULL);
00141
00142 int **arr_image = new int *[nHeight];
00143 for (int i = 0; i < nHeight; i++)
00144 {
00145 arr_image[i] = new int[nWidth];
00146 }
00147
00148 int x, y;
00149 int r, g, b;
00150 vector < CvPoint > red_points_vec;
00151 vector < CvPoint > detect_points_vec;
00152 vector < vector < CvPoint > >result_points_vec;
00153 CvPoint point;
00154
00155 for (y = 0; y < nHeight; y++)
00156 {
00157 for (x = 0; x < nWidth; x++)
00158 {
00159 r = ((unsigned char *) (image->imageData + image->widthStep * y))[x * 3 + 2];
00160 g = ((unsigned char *) (image->imageData + image->widthStep * y))[x * 3 + 1];
00161 b = ((unsigned char *) (image->imageData + image->widthStep * y))[x * 3];
00162
00163 if ((r > r_t) && (g < bg_t) && (b < bg_t) && (abs (g - b) < bg_diff))
00164 {
00165 arr_image[y][x] = 1;
00166 point.x = x;
00167 point.y = y;
00168 red_points_vec.push_back (point);
00169 }
00170 else
00171 arr_image[y][x] = 0;
00172 }
00173 }
00174 detect_points_vec.reserve (red_points_vec.size ());
00175 result_points_vec.reserve (red_points_vec.size ());
00176 for (int i = 0; i < (int) red_points_vec.size (); i++)
00177 {
00178 if (arr_image[red_points_vec[i].y][red_points_vec[i].x] == 1)
00179 {
00180 arr_image[red_points_vec[i].y][red_points_vec[i].x] = 0;
00181 detect_points_vec.push_back (red_points_vec[i]);
00182 vector < CvPoint >::iterator ptr = detect_points_vec.begin ();
00183 while (ptr != detect_points_vec.end ())
00184 {
00185 if (arr_image[ptr->y - 1][ptr->x] == 1)
00186 {
00187 point.x = ptr->x;
00188 point.y = ptr->y - 1;
00189 detect_points_vec.push_back (point);
00190 arr_image[ptr->y - 1][ptr->x] = 0;
00191 }
00192 if (arr_image[ptr->y][ptr->x + 1] == 1)
00193 {
00194 point.x = ptr->x + 1;
00195 point.y = ptr->y;
00196 detect_points_vec.push_back (point);
00197 arr_image[ptr->y][ptr->x + 1] = 0;
00198 }
00199 if (arr_image[ptr->y + 1][ptr->x] == 1)
00200 {
00201 point.x = ptr->x;
00202 point.y = ptr->y + 1;
00203 detect_points_vec.push_back (point);
00204 arr_image[ptr->y + 1][ptr->x] = 0;
00205 }
00206 if (arr_image[ptr->y][ptr->x - 1] == 1)
00207 {
00208 point.x = ptr->x - 1;
00209 point.y = ptr->y;
00210 detect_points_vec.push_back (point);
00211 arr_image[ptr->y][ptr->x - 1] = 0;
00212 }
00213 ptr++;
00214 }
00215 result_points_vec.push_back (detect_points_vec);
00216 detect_points_vec.clear ();
00217 ROS_INFO ("Find a class here");
00218 }
00219 else
00220 {
00221 continue;
00222 }
00223 }
00224
00225 for (int i = 0; i < nHeight; i++)
00226 {
00227 delete[]arr_image[i];
00228 }
00229 delete[]arr_image;
00230 ROS_INFO ("There are all %d classes", result_points_vec.size ());
00231
00232 int maxSize = (int) result_points_vec[0].size ();
00233 int k = 0;
00234 for (int i = 1; i < (int) result_points_vec.size (); i++)
00235 {
00236 if ((int) result_points_vec[i].size () > maxSize)
00237 {
00238 maxSize = (int) result_points_vec[i].size ();
00239 k = i;
00240 }
00241
00242 }
00243 ROS_INFO ("The biggst class has %d points", maxSize);
00244
00245 int min_x, min_y, max_x, max_y;
00246 min_x = result_points_vec[k][0].x;
00247 min_y = result_points_vec[k][0].y;
00248 max_x = result_points_vec[k][0].x;
00249 max_y = result_points_vec[k][0].y;
00250
00251 for (int i = 2; i < (int) result_points_vec[k].size (); i++)
00252 {
00253 if (result_points_vec[k][i].x > max_x)
00254 {
00255 max_x = result_points_vec[k][i].x;
00256 }
00257 if (result_points_vec[k][i].y > max_y)
00258 {
00259 max_y = result_points_vec[k][i].y;
00260 }
00261 if (result_points_vec[k][i].x < min_x)
00262 {
00263 min_x = result_points_vec[k][i].x;
00264 }
00265 if (result_points_vec[k][i].y < min_y)
00266 {
00267 min_y = result_points_vec[k][i].y;
00268 }
00269 }
00270 CvPoint min_point, max_point;
00271 min_point.x = min_x;
00272 min_point.y = min_y;
00273 max_point.x = max_x;
00274 max_point.y = max_y;
00275 cvRectangle (image, min_point, max_point, CV_RGB (0, 200, 0), 8, 8, 0);
00276
00277
00278 CvScalar s;
00279 IplImage *chessboard_image =
00280 cvCreateImage (cvSize (max_point.x - min_point.x + 1, max_point.y - min_point.y + 1), 8, 3);
00281 for (int i = min_point.y; i < max_point.y; i++)
00282 {
00283 for (int j = min_point.x; j < max_point.x; j++)
00284 {
00285 s.val[2] = ((unsigned char *) (raw_image->imageData + raw_image->widthStep * i))[j * 3 + 2];
00286 s.val[1] = ((unsigned char *) (raw_image->imageData + raw_image->widthStep * i))[j * 3 + 1];
00287 s.val[0] = ((unsigned char *) (raw_image->imageData + raw_image->widthStep * i))[j * 3];
00288 cvSet2D (chessboard_image, i - min_point.y, j - min_point.x, s);
00289 }
00290 }
00291
00292 IplImage *chessboard_grayimage_ = cvCreateImage (cvGetSize (chessboard_image), 8, 1);
00293 cvCvtColor (chessboard_image, chessboard_grayimage_, CV_RGB2GRAY);
00294 IplImage *chessboard_grayimage = cvCreateImage (cvGetSize (chessboard_image), 8, 1);
00295 bool bIsInteg = integralImageThresholding (chessboard_grayimage_, chessboard_grayimage, 0.15);
00296 if (bIsInteg)
00297 {
00298 ROS_INFO ("GOOD");
00299 }
00300 else
00301 {
00302 ROS_INFO ("Fail to thresholding");
00303 return -1;
00304 }
00305
00306 CvPoint2D32f *corners = new CvPoint2D32f[board_w * board_h];
00307 int corner_count;
00308 CvSize board_sz = cvSize (board_w, board_h);
00309
00310 int found = cvFindChessboardCorners (chessboard_grayimage,
00311 board_sz,
00312 corners,
00313 &corner_count,
00314 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
00315 ROS_INFO ("CORNER_COUMT = %d", corner_count);
00316 if (found == 1)
00317 {
00318 ROS_INFO ("FIND CORNERS OK");
00319 }
00320 else
00321 ROS_INFO ("FAIL TO FIND CORNERS");
00322
00323 cvFindCornerSubPix (chessboard_grayimage, corners, corner_count, cvSize (11, 11), cvSize (-1, -1),
00324 cvTermCriteria (CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
00325
00326 CvPoint corner_point[corner_count];
00327 CvPoint corner_point_raw[corner_count];
00328
00329 ofstream my_w ("visionpts.txt");
00330 if (!my_w.is_open ())
00331 {
00332 ROS_INFO ("open the file visionpts.txt fail\n");
00333 return -1;
00334 }
00335 else
00336 ROS_INFO ("open the file ok\n");
00337
00338 for (int i = 0; i < corner_count; i++)
00339 {
00340 corner_point[i].x = corners[i].x;
00341 corner_point[i].y = corners[i].y;
00342 corner_point_raw[i].x = corners[i].x + min_point.x;
00343 corner_point_raw[i].y = corners[i].y + min_point.y;
00344 my_w << corner_point_raw[i].x * 1.0 << " " << corner_point_raw[i].y * 1.0 << "\n";
00345
00346 }
00347 my_w.close ();
00348
00349 for (int i = 0; i < corner_count; i++)
00350 {
00351 cvCircle (chessboard_grayimage, corner_point[i], 5, CV_RGB (200, 0, 0));
00352 cvCircle (raw_image, corner_point_raw[i], 5, CV_RGB (200, 0, 0));
00353
00354 }
00355 delete[]corners;
00356
00357 cvNamedWindow ("detect_egde", 0);
00358 cvNamedWindow ("detect_corners", 0);
00359 cvNamedWindow ("raw_image", 0);
00360 cvShowImage ("detect_egde", image);
00361 cvShowImage ("detect_corners", chessboard_grayimage);
00362 cvShowImage ("raw_image", raw_image);
00363 cvWaitKey (0);
00364 cvDestroyWindow ("detect_egde");
00365 cvDestroyWindow ("detect_corners");
00366 cvDestroyWindow ("raw_image");
00367 cvReleaseImage (&image);
00368 cvReleaseImage (&chessboard_grayimage);
00369 cvReleaseImage (&raw_image);
00370
00371 return 0;
00372 }