/src/filter.cc

https://github.com/vbajpai/imagefilters · C++ · 290 lines · 209 code · 70 blank · 11 comment · 42 complexity · 1883613d10a8bdbefd7f4b4100ba30ce MD5 · raw file

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. using namespace std;
  4. class Filters{
  5. private:
  6. IplImage* src;
  7. IplImage* dst;
  8. public:
  9. Filters(){}
  10. Filters(IplImage* img){
  11. src = img;
  12. }
  13. void setSource(IplImage *img){src = img;}
  14. IplImage* doBlur(){
  15. dst = cvCloneImage(src);
  16. cvSmooth(src, dst, CV_BLUR, 5, 5, 0, 0);
  17. return dst;
  18. }
  19. IplImage* doGauss(){
  20. dst = cvCloneImage(src);
  21. cvSmooth(src, dst, CV_GAUSSIAN, 5, 5, 0, 0);
  22. return dst;
  23. }
  24. IplImage* doSobel(){
  25. dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 3);
  26. cvSobel(src, dst, 1, 0, 3);
  27. IplImage* returnDst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
  28. cvConvertScale(dst,returnDst, 1, 0);
  29. return returnDst;
  30. }
  31. IplImage* doCanny(){
  32. /* convert to gray scale */
  33. IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  34. cvCvtColor(src, dst, CV_RGB2GRAY);
  35. cvCanny(dst, dst, 80, 160, 3);
  36. return dst;
  37. }
  38. IplImage* doHough(){
  39. /* preprocess with canny */
  40. IplImage* img = doCanny();
  41. /* create a memory storage */
  42. CvMemStorage *storage = cvCreateMemStorage(0);
  43. CvSeq* line = cvHoughLines2(img, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 100, 100, 10);
  44. for (int i=0; i<line->total; i++) {
  45. CvPoint* lineEndPoints = (CvPoint*) cvGetSeqElem(line,i);
  46. cvLine(src, lineEndPoints[0], lineEndPoints[1], CV_RGB(255,0,0), 2);
  47. }
  48. return src;
  49. }
  50. IplImage* doSkin(){
  51. /* convert to YCrCb */
  52. IplImage* srcYCrCb = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
  53. cvCvtColor(src, srcYCrCb, CV_BGR2YCrCb);
  54. /* split channels */
  55. IplImage* srcR = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  56. IplImage* srcG = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  57. IplImage* srcB = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  58. IplImage* srcY = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  59. IplImage* srcCr = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  60. IplImage* srcCb = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
  61. cvSplit(src, srcB, srcG, srcR, NULL);
  62. cvSplit(srcYCrCb, srcY, srcCr, srcCb, NULL);
  63. /* access image pixels */
  64. for (int i=0; i<(srcCr->height); i++){
  65. for (int j=0; j<(srcCr->width); j++){
  66. double crPixelValue = cvGetReal2D(srcCr, i, j);
  67. double cbPixelValue = cvGetReal2D(srcCb, i, j);
  68. double rPixelValue = cvGetReal2D(srcR, i, j);
  69. double gPixelValue = cvGetReal2D(srcG, i, j);
  70. double bPixelValue = cvGetReal2D(srcB, i, j);
  71. if ((rPixelValue > 95 && gPixelValue > 40 && bPixelValue > 20) &&
  72. (fabs(rPixelValue - gPixelValue) > 15) &&
  73. (rPixelValue > gPixelValue && rPixelValue > bPixelValue)){
  74. if ((crPixelValue > 135 && crPixelValue < 180) &&
  75. (cbPixelValue > 85 && cbPixelValue < 135)) {
  76. }
  77. }
  78. else{
  79. /* set non-skin pixels to black */
  80. CvScalar s = cvGet2D(src, i, j);
  81. s.val[0]=0;s.val[1]=0;s.val[2]=0;
  82. cvSet2D(src,i,j,s);
  83. }
  84. }
  85. }
  86. return src;
  87. }
  88. };
  89. class FilterBySource: public Filters{
  90. private:
  91. string filtername;
  92. IplImage* callFilterFromFiltername(){
  93. if(!filtername.compare("-blur"))
  94. return doBlur();
  95. else if(!filtername.compare("-gauss"))
  96. return doGauss();
  97. else if(!filtername.compare("-sobel"))
  98. return doSobel();
  99. else if(!filtername.compare("-canny"))
  100. return doCanny();
  101. else if(!filtername.compare("-hough"))
  102. return doHough();
  103. else if(!filtername.compare("-skin"))
  104. return doSkin();
  105. else
  106. return NULL;
  107. }
  108. public:
  109. FilterBySource(string filtername){this->filtername = filtername;}
  110. void filterLiveCapture(){
  111. /* allocate resources */
  112. cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
  113. cvNamedWindow("Filtered", CV_WINDOW_AUTOSIZE);
  114. CvCapture* capture = cvCaptureFromCAM(0);
  115. do {
  116. IplImage* img = cvQueryFrame(capture);
  117. cvShowImage("Original", img);
  118. IplImage* imgClone = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
  119. imgClone = cvCloneImage(img);
  120. setSource(imgClone);
  121. IplImage* dst = callFilterFromFiltername();
  122. cvShowImage("Filtered", dst);
  123. cvWaitKey(10);
  124. } while (1);
  125. /* deallocate resources */
  126. cvDestroyWindow("Original");
  127. cvDestroyWindow("Filtered");
  128. cvReleaseCapture(&capture);
  129. }
  130. int filterImage(string filename){
  131. IplImage* img = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_UNCHANGED);
  132. if (img!=NULL){
  133. cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
  134. cvNamedWindow("Filtered", CV_WINDOW_AUTOSIZE);
  135. cvShowImage("Original", img);
  136. setSource(img);
  137. IplImage* dst = callFilterFromFiltername();
  138. cvShowImage("Filtered", dst);
  139. cin.get();
  140. cvDestroyWindow("Original");
  141. cvDestroyWindow("Filtered");
  142. return 0;
  143. }
  144. else
  145. return 1;
  146. }
  147. int filterVideo(string filename){
  148. CvCapture* capture = cvCaptureFromFile(filename.c_str());
  149. if (capture!=NULL){
  150. /* allocate resources */
  151. cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
  152. cvNamedWindow("Filtered", CV_WINDOW_AUTOSIZE);
  153. do {
  154. IplImage* img = cvQueryFrame(capture);
  155. cvShowImage("Original", img);
  156. IplImage* imgClone = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
  157. imgClone = cvCloneImage(img);
  158. setSource(imgClone);
  159. IplImage* dst = callFilterFromFiltername();
  160. cvShowImage("Filtered", dst);
  161. cvWaitKey(1);
  162. } while (1);
  163. /* deallocate resources */
  164. cvDestroyWindow("Original");
  165. cvDestroyWindow("Filtered");
  166. cvReleaseCapture(&capture);
  167. return 0;
  168. }
  169. else
  170. return 1;
  171. }
  172. bool static ifFilterAvailable(string filtername){
  173. if(filtername.compare("-blur") &&
  174. filtername.compare("-gauss") &&
  175. filtername.compare("-sobel") &&
  176. filtername.compare("-canny") &&
  177. filtername.compare("-hough") &&
  178. filtername.compare("-skin"))
  179. return false;
  180. else
  181. return true;
  182. }
  183. };
  184. int main(int argc, char* argv[]){
  185. if (argc == 2 || argc == 4){
  186. string filtername = argv[1];
  187. bool ifFilter = FilterBySource::ifFilterAvailable(filtername);
  188. if(ifFilter){
  189. FilterBySource *filterBySource = new FilterBySource(filtername);
  190. if (argc == 2)
  191. filterBySource -> filterLiveCapture();
  192. else{
  193. char flag = *(argv[2] + 1);
  194. flag = tolower(flag);
  195. if (flag == 'i' || flag == 'v'){
  196. string filename = argv[3];
  197. if (flag == 'i'){
  198. if(filterBySource -> filterImage(filename))
  199. cout << "cannot load file";
  200. }
  201. else{
  202. if(filterBySource -> filterVideo(filename))
  203. cout << "cannot load file";
  204. }
  205. }
  206. }
  207. delete(filterBySource);
  208. }
  209. else{
  210. cout << "filter not available" << endl;
  211. return 0;
  212. }
  213. }
  214. else{
  215. cout << "usage: " << argv[0] << " <filterName> [<filenameFlag> <filename>]" << endl;
  216. cout << "filterName: [-blur] | [-gauss] | [-sobel] | [-canny] | [-hough] | [-skin]" << endl;
  217. cout << "filenameFlag: [-i] | [-v]" << endl;
  218. }
  219. return 0;
  220. }