PageRenderTime 650ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/saliency/src/main.cpp

https://github.com/jgrogers/Door-Sign-Detection
C++ | 288 lines | 243 code | 27 blank | 18 comment | 36 complexity | 90183d89bd3950fa0d2bedd9ca328699 MD5 | raw file
  1. #include <saliency.h>
  2. #include <boost/program_options.hpp>
  3. #include <iostream>
  4. #include <Blob.h>
  5. #include <BlobResult.h>
  6. #include <highgui.h>
  7. #include <cv.h>
  8. #include <cvaux.h>
  9. int thresh = 350;
  10. int scale = 6;
  11. void on_trackbar( int position) {
  12. thresh = position;
  13. }
  14. void on_scalebar( int position) {
  15. scale = position;
  16. }
  17. namespace po = boost::program_options;
  18. void cvShowImageSmall(const char* name, const IplImage* img) {
  19. // IplImage* img_show =cvCreateImage(cvSize(640,480), img->depth, img->nChannels);
  20. // cvResize(img, img_show);
  21. cvShowImage(name, img);
  22. // cvReleaseImage(&img_show);
  23. }
  24. CvRect GetSquareRegion(CvPoint ul, CvPoint lr) {
  25. int width = abs(lr.x - ul.x);
  26. int height = abs(lr.y - ul.y);
  27. int cx = ul.x + width/2;
  28. int cy = ul.y + height/2;
  29. CvRect result;
  30. if (width > height) {
  31. result = cvRect(ul.x, cy - width/2, width,width);
  32. }
  33. else {
  34. result = cvRect(cx - height/2, ul.y, height,height);
  35. }
  36. return result;
  37. }
  38. std::vector<CvRect> GetOverlappedSquareRegions(const std::vector<CvRect>& rects) {
  39. //merge overlapping squares
  40. std::vector<CvRect> out_rects = rects;
  41. bool overlap_found = false;
  42. do {
  43. overlap_found = false;
  44. std::vector<CvRect> tmp_rects;
  45. std::vector<bool> rect_incorporated;
  46. for (size_t i = 0;i<out_rects.size();i++)
  47. rect_incorporated.push_back(false);
  48. size_t i = 0;
  49. //check each pair of rects to merge if possible
  50. for (std::vector<CvRect>::iterator itr = out_rects.begin();
  51. itr != out_rects.end();
  52. itr++) {
  53. if (rect_incorporated[i]) continue; //already used this one this time
  54. rect_incorporated[i] = true;
  55. int min_x = itr->x;
  56. int min_y = itr->y;
  57. int max_x = itr->x + itr->width;
  58. int max_y = itr->y + itr->height;
  59. size_t j = i+1;
  60. for (std::vector<CvRect>::iterator itr2 = itr+1;
  61. itr2 != out_rects.end();
  62. itr2++) {
  63. bool x_cond = false;
  64. bool y_cond = false;
  65. if (
  66. (itr2->x >= min_x &&
  67. itr2->x <= max_x) ||
  68. (itr2->x + itr2->width >= min_x &&
  69. itr2->x + itr2->width <= max_x) ||
  70. (min_x >= itr2->x &&
  71. min_x <= itr2->x+itr2->width) ||
  72. (max_x >= itr2->x &&
  73. max_x <= itr2->x+itr2->width ))
  74. x_cond = true;
  75. if (
  76. (itr2->y >= min_y &&
  77. itr2->y <= max_y) ||
  78. (itr2->y + itr2->height >= min_y &&
  79. itr2->y + itr2->height <= max_y) ||
  80. (min_y >= itr2->y &&
  81. min_y <= itr2->y+itr2->height) ||
  82. (max_y >= itr2->y &&
  83. max_y <= itr2->y+itr2->height ))
  84. y_cond = true;
  85. if (x_cond && y_cond) {
  86. overlap_found = true;
  87. rect_incorporated[j] = true;
  88. min_x = MIN(min_x, itr2->x);
  89. max_x = MAX(max_x, itr2->x+itr2->width);
  90. min_y = MIN(min_y, itr2->y);
  91. max_y = MAX(max_y, itr2->y+itr2->height);
  92. }
  93. j++;
  94. }
  95. i++;
  96. tmp_rects.push_back(cvRect(min_x, min_y, max_x - min_x, max_y - min_y));
  97. }
  98. out_rects = tmp_rects;
  99. } while(overlap_found == true);
  100. return out_rects;
  101. }
  102. int main(int argc, char** argv) {
  103. unsigned int uint_opt;
  104. double double_opt;
  105. po::options_description desc("Allowed options");
  106. desc.add_options()
  107. ("help", "produce help message")
  108. ("img", po::value<std::string>(), "Load this file for detect saliency")
  109. ("saliency", "run saliency test")
  110. ("saliency_blobs", "run saliency test")
  111. ("edge", "run edge test")
  112. ("conv_rect", "run the convolution rectangle test")
  113. ("hog", "HOG feature test")
  114. ;
  115. po::variables_map vm;
  116. po::store(po::parse_command_line(argc, argv, desc),vm);
  117. po::notify(vm);
  118. if (vm.count("help")) {
  119. std::cout <<desc<<"\n";
  120. return 1;
  121. }
  122. cvNamedWindow("output",1);
  123. cvNamedWindow("Input",1);
  124. cvCreateTrackbar("Threshold", "output", &thresh, 1000, on_trackbar);
  125. cvCreateTrackbar("Scale", "output", &scale, 10, on_scalebar);
  126. // move the new window to a better place
  127. cvMoveWindow ("Camera", 10, 10);
  128. if (vm.count("img")) {
  129. unsigned int key = -1;
  130. do {
  131. IplImage* img_in = cvLoadImage(vm["img"].as<std::string>().c_str());
  132. IplImage* img_tmp = cvCreateImage(cvSize(1024,768), IPL_DEPTH_8U, 3);
  133. cvResize(img_in, img_tmp);
  134. cvReleaseImage(&img_in);
  135. img_in = img_tmp;
  136. cvSmooth(img_in,img_in,3);
  137. if (vm.count ("conv_rect")) {
  138. IplImage* img_tmp = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U,1);
  139. IplImage* img_out;// = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1);
  140. cvCvtColor(img_in, img_tmp, CV_BGR2GRAY);
  141. //img_out = ConvRect(img_tmp, thresh, scale);
  142. cvShowImageSmall("Input", img_in);
  143. cvShowImageSmall("output",img_out);
  144. cvReleaseImage(&img_tmp);
  145. cvReleaseImage(&img_out);
  146. }
  147. if (vm.count ("edge")) {
  148. IplImage* img_tmp = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U,1);
  149. IplImage* img_out = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1);
  150. cvCvtColor(img_in, img_tmp, CV_BGR2GRAY);
  151. cvCanny(img_tmp,img_out,thresh,thresh*2);
  152. cvShowImageSmall("Input", img_in);
  153. cvShowImageSmall("output", img_out);
  154. cvReleaseImage(&img_tmp);
  155. cvReleaseImage(&img_out);
  156. }
  157. if (vm.count ("hog")){
  158. IplImage* tmp_img = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1);
  159. cvCvtColor(img_in, tmp_img, CV_BGR2GRAY);
  160. //cv::HOGDescriptor hog(cvSize(3648,2736),cvSize(16,16),cvSize(8,8),cvSize(8,8),9,1,-1);
  161. cv::HOGDescriptor hog(cvSize(128,128),cvSize(16,16),cvSize(8,8),cvSize(8,8),9,1,-1);
  162. printf("computing...\n");
  163. std::vector<float> desc;
  164. hog.compute(tmp_img,desc);
  165. printf("computed...\n");
  166. printf("desc len: %d\n",desc.size());
  167. }
  168. if (vm.count("saliency")) {
  169. IplImage* tmp_img = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1);
  170. cvCvtColor(img_in, tmp_img, CV_BGR2GRAY);
  171. IplImage* img_out = ComputeSaliency(tmp_img, thresh, scale);
  172. cvShowImageSmall("Input", tmp_img);
  173. cvReleaseImage(&tmp_img);
  174. cvShowImageSmall("output",img_out);
  175. cvReleaseImage(&img_out);
  176. }
  177. if (vm.count ("saliency_blobs")) {
  178. IplImage* tmp_img = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1);
  179. cvCvtColor(img_in, tmp_img, CV_BGR2GRAY);
  180. IplImage* img_out = ComputeSaliency(tmp_img, thresh, scale);
  181. IplImage* displayedImage = cvCreateImage(cvGetSize(img_out), IPL_DEPTH_8U, 3);
  182. CBlobResult blobs;
  183. int i;
  184. CBlob *currentBlob;
  185. // find non-white blobs in thresholded image
  186. blobs = CBlobResult( img_out, NULL, 127, 255 );
  187. // exclude the ones smaller than param2 value
  188. blobs.Filter( blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 20 );
  189. // get mean gray color of biggest blob
  190. // display filtered blobs
  191. cvMerge( img_out, img_out, img_out, NULL, displayedImage );
  192. printf("Found %d blobs\n",
  193. blobs.GetNumBlobs());
  194. std::vector<CvRect> in_rects;
  195. for (i = 2; i < blobs.GetNumBlobs(); i++ )
  196. {
  197. currentBlob = blobs.GetBlob(i);
  198. if ((currentBlob->minx == 0.0) &&
  199. (currentBlob->miny == 0.0) &&
  200. (currentBlob->maxx == 0.0) &&
  201. (currentBlob->maxy == 0.0)){
  202. printf("blob bbox: %f %f %f %f\n",currentBlob->minx, currentBlob->miny,currentBlob->maxx,currentBlob->maxy);
  203. } else {
  204. printf("blob bbox: %f %f %f %f\n",currentBlob->minx, currentBlob->miny,currentBlob->maxx,currentBlob->maxy);
  205. //currentBlob->FillBlob( displayedImage, CV_RGB(255-i*255/blobs.GetNumBlobs(),i*255/blobs.GetNumBlobs(),0));
  206. //CvRect square = GetSquareRegion(cvPoint(currentBlob->minx, currentBlob->miny),
  207. //cvPoint(currentBlob->maxx, currentBlob->maxy));
  208. CvRect square = cvRect(currentBlob->minx, currentBlob->miny,currentBlob->maxx - currentBlob->minx, currentBlob->maxy - currentBlob->miny);
  209. in_rects.push_back(square);
  210. cvRectangle(displayedImage, cvPoint(square.x, square.y),
  211. cvPoint(square.x + square.width, square.y + square.height),
  212. CV_RGB(0,0,255),3);
  213. cvSetImageROI(tmp_img, square);
  214. square.width = 16;
  215. square.height = 16;
  216. //CvMat* newmat = cvCreateMat(square.width, square.height,CV_8UC1);
  217. CvMat* newmat = cvCreateMat(square.height, square.width,CV_8UC1);
  218. cv::HOGDescriptor hog(cvSize(square.width,square.height),
  219. cvSize(16,16),
  220. cvSize(4,4),
  221. cvSize(4,4),
  222. 8,1,-1);
  223. cvResize(tmp_img, newmat);
  224. cv::Mat tmpmat(newmat, true);
  225. //cv::Mat grad, qangle;
  226. cv::Size paddingTL = cvSize(1,1);
  227. cv::Size paddingBR = cvSize(1,1);
  228. std::vector<float> descriptor;
  229. //hog.computeGradient(tmpmat, grad, qangle, paddingTL, paddingBR);
  230. hog.compute(tmpmat,descriptor);
  231. printf("descriptor len: %d\n",descriptor.size());
  232. for(int k = 0; k < descriptor.size(); k++){
  233. printf("%f,",descriptor[k]);
  234. }
  235. printf("\n");
  236. hog.save("testhog.hog","blah");
  237. cvResetImageROI(tmp_img);
  238. }
  239. }
  240. std::vector<CvRect>out_rects = GetOverlappedSquareRegions(in_rects);
  241. for (std::vector<CvRect>::iterator itr = out_rects.begin();
  242. itr != out_rects.end();
  243. itr++) {
  244. cvRectangle(img_in, cvPoint(itr->x, itr->y),
  245. cvPoint(itr->x + itr->width, itr->y + itr->height),
  246. CV_RGB(0,255,0),5);
  247. }
  248. cvShowImageSmall("Input", img_in);
  249. if (blobs.GetNumBlobs()< 200)
  250. blobs.PrintBlobs("test.out");
  251. cvShowImageSmall("output",displayedImage);
  252. cvReleaseImage(&img_out);
  253. cvReleaseImage(&displayedImage);
  254. cvReleaseImage(&tmp_img);
  255. }
  256. key = cvWaitKey(30);
  257. cvReleaseImage(&img_in);
  258. }while (key != 'q');
  259. }
  260. return -1;
  261. }