diff --git a/sample/retro_sample.cpp b/sample/retro_sample.cpp index d4b031e..a146e9b 100644 --- a/sample/retro_sample.cpp +++ b/sample/retro_sample.cpp @@ -85,18 +85,24 @@ int main(int argc, const char** argv) } Mat frame; - capture >> frame; - - if (frame.empty()) + const int maxAttemps = 5; // attempt to get first non-empty frame + int attemptIdx = 0; + while (frame.empty() && attemptIdx < maxAttemps) { - // empty video; lets consider this to be OK - return 0; + capture >> frame; + attemptIdx++; + } + if (attemptIdx == maxAttemps) + { + cout << "Error: empty first frames." << endl; + return 1; } + params.frameSize = frame.size(); RetroFilter filter(params); - for(;;) + while (!frame.empty()) { Mat retroFrame; TS(filter); @@ -110,7 +116,6 @@ int main(int argc, const char** argv) break; capture >> frame; - if(frame.empty()) break; } return 0; diff --git a/src/retro_filter.cpp b/src/retro_filter.cpp index 5956869..8bfcee1 100644 --- a/src/retro_filter.cpp +++ b/src/retro_filter.cpp @@ -1,5 +1,6 @@ #include "retro_filter.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include using namespace std; using namespace cv; @@ -11,9 +12,8 @@ inline void alphaBlend(const Mat& src, Mat& dst, const Mat& alpha) src.convertTo(s, CV_32S); dst.convertTo(d, CV_32S); - multiply(s, w, sw); - multiply(d, -w, dw); - d = (d*255 + sw + dw)/255.0; + multiply(s - d, w, sw); + d = (d*255 + sw)/255.0; d.convertTo(dst, CV_8U); } @@ -36,24 +36,25 @@ RetroFilter::RetroFilter(const Parameters& params) : rng_(time(0)) void RetroFilter::applyToVideo(const Mat& frame, Mat& retroFrame) { int col, row; - Mat luminance; + Mat luminance; cvtColor(frame, luminance, CV_BGR2GRAY); // Add scratches - Scalar meanColor = mean(luminance.row(luminance.rows / 2)); - Mat scratchColor(params_.frameSize, CV_8UC1, meanColor * 2.0); + Scalar meanColor = mean(luminance.row(luminance.rows / 2)); //!!! + Mat scratchColor(params_.frameSize, CV_8UC1, meanColor * 2.0); int x = rng_.uniform(0, params_.scratches.cols - luminance.cols); int y = rng_.uniform(0, params_.scratches.rows - luminance.rows); - for (row = 0; row < luminance.size().height; row += 1) + for (row = 0; row < luminance.size().height; row++) { - for (col = 0; col < luminance.size().width; col += 1) + for (col = 0; col < luminance.size().width; col++) { - uchar pix_color = params_.scratches.at(row + y, col + x) ? (int)scratchColor.at(row, col) : luminance.at(row, col); - luminance.at(row, col) = pix_color; + luminance.at(row, col) = params_.scratches.at(row + y, col + x) ? (int)scratchColor.at(row, col) : luminance.at(row, col); } } + + // Add fuzzy border Mat borderColor(params_.frameSize, CV_32FC1, Scalar::all(meanColor[0] * 1.5)); alphaBlend(borderColor, luminance, params_.fuzzyBorder); @@ -61,21 +62,13 @@ void RetroFilter::applyToVideo(const Mat& frame, Mat& retroFrame) // Apply sepia-effect retroFrame.create(luminance.size(), CV_8UC3); - Mat hsv_pixel(1, 1, CV_8UC3); - Mat rgb_pixel(1, 1, CV_8UC3); - for (col = 0; col < luminance.size().width; col += 1) - { - for (row = 0; row < luminance.size().height; row += 1) - { - hsv_pixel.ptr()[2] = cv::saturate_cast(luminance.at(row, col) * hsvScale_ + hsvOffset_); - hsv_pixel.ptr()[0] = 19; - hsv_pixel.ptr()[1] = 78; + vector channels; + split(retroFrame, channels); + channels[0] = 19; + channels[1] = 78; + channels[2] = luminance * hsvScale_ + hsvOffset_; + merge(channels, retroFrame); - cvtColor(hsv_pixel, rgb_pixel, CV_HSV2RGB); + cvtColor(retroFrame, retroFrame, CV_HSV2BGR); - retroFrame.at(row, col)[0] = rgb_pixel.ptr()[2]; - retroFrame.at(row, col)[1] = rgb_pixel.ptr()[1]; - retroFrame.at(row, col)[2] = rgb_pixel.ptr()[0]; - } - } }