live_demo.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * By downloading, copying, installing or using the software you agree to this license.
  3. * If you do not agree to this license, do not download, install,
  4. * copy or use the software.
  5. *
  6. *
  7. * License Agreement
  8. * For Open Source Computer Vision Library
  9. * (3 - clause BSD License)
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification,
  12. * are permitted provided that the following conditions are met :
  13. *
  14. * * Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright notice,
  18. * this list of conditions and the following disclaimer in the documentation
  19. * and / or other materials provided with the distribution.
  20. *
  21. * * Neither the names of the copyright holders nor the names of the contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * This software is provided by the copyright holders and contributors "as is" and
  26. * any express or implied warranties, including, but not limited to, the implied
  27. * warranties of merchantability and fitness for a particular purpose are disclaimed.
  28. * In no event shall copyright holders or contributors be liable for any direct,
  29. * indirect, incidental, special, exemplary, or consequential damages
  30. * (including, but not limited to, procurement of substitute goods or services;
  31. * loss of use, data, or profits; or business interruption) however caused
  32. * and on any theory of liability, whether in contract, strict liability,
  33. * or tort(including negligence or otherwise) arising in any way out of
  34. * the use of this software, even if advised of the possibility of such damage.
  35. */
  36. #include <opencv2/core.hpp>
  37. #include <opencv2/core/utility.hpp>
  38. #include <opencv2/highgui.hpp>
  39. #include <opencv2/imgproc.hpp>
  40. #include <opencv2/ximgproc.hpp>
  41. using namespace cv;
  42. using namespace cv::ximgproc;
  43. #include <iostream>
  44. using namespace std;
  45. typedef void(*FilteringOperation)(const Mat& src, Mat& dst);
  46. //current mode (filtering operation example)
  47. FilteringOperation g_filterOp = NULL;
  48. //list of filtering operations
  49. void filterDoNothing(const Mat& frame, Mat& dst);
  50. void filterBlurring(const Mat& frame, Mat& dst);
  51. void filterStylize(const Mat& frame, Mat& dst);
  52. void filterDetailEnhancement(const Mat& frame8u, Mat& dst);
  53. //common sliders for every mode
  54. int g_sigmaColor = 25;
  55. int g_sigmaSpatial = 10;
  56. //for Stylizing mode
  57. int g_edgesGamma = 100;
  58. //for Details Enhancement mode
  59. int g_contrastBase = 100;
  60. int g_detailsLevel = 100;
  61. int g_numberOfCPUs = cv::getNumberOfCPUs();
  62. //We will use two callbacks to change parameters
  63. void changeModeCallback(int state, void *filter);
  64. void changeNumberOfCpuCallback(int count, void*);
  65. void splitScreen(const Mat& rawFrame, Mat& outputFrame, Mat& srcFrame, Mat& processedFrame);
  66. //trivial filter
  67. void filterDoNothing(const Mat& frame, Mat& dst)
  68. {
  69. frame.copyTo(dst);
  70. }
  71. //simple edge-aware blurring
  72. void filterBlurring(const Mat& frame, Mat& dst)
  73. {
  74. dtFilter(frame, frame, dst, g_sigmaSpatial, g_sigmaColor, DTF_RF);
  75. }
  76. //stylizing filter
  77. void filterStylize(const Mat& frame, Mat& dst)
  78. {
  79. //blur frame
  80. Mat filtered;
  81. dtFilter(frame, frame, filtered, g_sigmaSpatial, g_sigmaColor, DTF_NC);
  82. //compute grayscale blurred frame
  83. Mat filteredGray;
  84. cvtColor(filtered, filteredGray, COLOR_BGR2GRAY);
  85. //find gradients of blurred image
  86. Mat gradX, gradY;
  87. Sobel(filteredGray, gradX, CV_32F, 1, 0, 3, 1.0/255);
  88. Sobel(filteredGray, gradY, CV_32F, 0, 1, 3, 1.0/255);
  89. //compute magnitude of gradient and fit it accordingly the gamma parameter
  90. Mat gradMagnitude;
  91. magnitude(gradX, gradY, gradMagnitude);
  92. cv::pow(gradMagnitude, g_edgesGamma/100.0, gradMagnitude);
  93. //multiply a blurred frame to the value inversely proportional to the magnitude
  94. Mat multiplier = 1.0/(1.0 + gradMagnitude);
  95. cvtColor(multiplier, multiplier, COLOR_GRAY2BGR);
  96. multiply(filtered, multiplier, dst, 1, dst.type());
  97. }
  98. void filterDetailEnhancement(const Mat& frame8u, Mat& dst)
  99. {
  100. Mat frame;
  101. frame8u.convertTo(frame, CV_32F, 1.0/255);
  102. //Decompose image to 3 Lab channels
  103. Mat frameLab, frameLabCn[3];
  104. cvtColor(frame, frameLab, COLOR_BGR2Lab);
  105. split(frameLab, frameLabCn);
  106. //Generate progressively smoother versions of the lightness channel
  107. Mat layer0 = frameLabCn[0]; //first channel is original lightness
  108. Mat layer1, layer2;
  109. dtFilter(layer0, layer0, layer1, g_sigmaSpatial, g_sigmaColor, DTF_IC);
  110. dtFilter(layer1, layer1, layer2, 2*g_sigmaSpatial, g_sigmaColor, DTF_IC);
  111. //Compute detail layers
  112. Mat detailLayer1 = layer0 - layer1;
  113. Mat detailLayer2 = layer1 - layer2;
  114. double cBase = g_contrastBase / 100.0;
  115. double cDetails1 = g_detailsLevel / 100.0;
  116. double cDetails2 = 2.0 - g_detailsLevel / 100.0;
  117. //Generate lightness
  118. double meanLigtness = mean(frameLabCn[0])[0];
  119. frameLabCn[0] = cBase*(layer2 - meanLigtness) + meanLigtness; //fit contrast of base (most blurred) layer
  120. frameLabCn[0] += cDetails1*detailLayer1; //add weighted sum of detail layers to new lightness
  121. frameLabCn[0] += cDetails2*detailLayer2; //
  122. //Update new lightness
  123. merge(frameLabCn, 3, frameLab);
  124. cvtColor(frameLab, frame, COLOR_Lab2BGR);
  125. frame.convertTo(dst, CV_8U, 255);
  126. }
  127. void changeModeCallback(int state, void *filter)
  128. {
  129. if (state == 1)
  130. g_filterOp = (FilteringOperation) filter;
  131. }
  132. void changeNumberOfCpuCallback(int count, void*)
  133. {
  134. count = std::max(1, count);
  135. g_numberOfCPUs = count;
  136. }
  137. //divide screen on two parts: srcFrame and processed Frame
  138. void splitScreen(const Mat& rawFrame, Mat& outputFrame, Mat& srcFrame, Mat& processedFrame)
  139. {
  140. int h = rawFrame.rows;
  141. int w = rawFrame.cols;
  142. int cn = rawFrame.channels();
  143. outputFrame.create(h, 2 * w, CV_MAKE_TYPE(CV_8U, cn));
  144. srcFrame = outputFrame(Range::all(), Range(0, w));
  145. processedFrame = outputFrame(Range::all(), Range(w, 2 * w));
  146. rawFrame.convertTo(srcFrame, srcFrame.type());
  147. }
  148. int main()
  149. {
  150. VideoCapture cap(0);
  151. if (!cap.isOpened())
  152. {
  153. cerr << "Capture device was not found" << endl;
  154. return -1;
  155. }
  156. namedWindow("Demo");
  157. displayOverlay("Demo", "Press Ctrl+P to show property window", 5000);
  158. //Thread trackbar
  159. createTrackbar("Threads", String(), &g_numberOfCPUs, cv::getNumberOfCPUs(), changeNumberOfCpuCallback);
  160. //Buttons to choose different modes
  161. createButton("Mode Details Enhancement", changeModeCallback, (void*)filterDetailEnhancement, QT_RADIOBOX, true);
  162. createButton("Mode Stylizing", changeModeCallback, (void*)filterStylize, QT_RADIOBOX, false);
  163. createButton("Mode Blurring", changeModeCallback, (void*)filterBlurring, QT_RADIOBOX, false);
  164. createButton("Mode DoNothing", changeModeCallback, (void*)filterDoNothing, QT_RADIOBOX, false);
  165. //sliders for Details Enhancement mode
  166. g_filterOp = filterDetailEnhancement; //set Details Enhancement as default filter
  167. createTrackbar("Detail contrast", String(), &g_contrastBase, 200);
  168. createTrackbar("Detail level" , String(), &g_detailsLevel, 200);
  169. //sliders for Stylizing mode
  170. createTrackbar("Style gamma", String(), &g_edgesGamma, 300);
  171. //sliders for every mode
  172. createTrackbar("Sigma Spatial", String(), &g_sigmaSpatial, 200);
  173. createTrackbar("Sigma Color" , String(), &g_sigmaColor, 200);
  174. Mat rawFrame, outputFrame;
  175. Mat srcFrame, processedFrame;
  176. for (;;)
  177. {
  178. do
  179. {
  180. cap >> rawFrame;
  181. } while (rawFrame.empty());
  182. cv::setNumThreads(g_numberOfCPUs); //speedup filtering
  183. splitScreen(rawFrame, outputFrame, srcFrame, processedFrame);
  184. g_filterOp(srcFrame, processedFrame);
  185. imshow("Demo", outputFrame);
  186. if (waitKey(1) == 27) break;
  187. }
  188. return 0;
  189. }