索引地址:系列索引
超分辨率(Super Resolution)指的是分辨率较高的比如4K、8K等等,但是一般这个做动词,指将低分辨率的视频图片通过某种方法变为高分辨率的行为,考虑到原始数据的状况,一般就是720P/1080P这样。
泰坦尼克号、终结者2这样的电影有过高清修复重映,一般就是将分辨率放大提高画质。这些都是胶片拍摄的。像一些电影、动漫等等,我们不是制作方没有原始数据,那么就只能通过软件的方式提升画质。
下面介绍OpenCV提供的超分辨率方法,实际在使用时一般使用神经网络+深度学习方法。比如
waifu2x SRMD Anime4k Realsr … 一些工具比如SFVI等工具就是整合上面的一些工具。
测试1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 #include <iostream> #include <iomanip> #include <string> #include "opencv2/core.hpp" #include "opencv2/core/utility.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/superres.hpp" #include "opencv2/superres/optical_flow.hpp" #include "opencv2/opencv_modules.hpp" using namespace std;using namespace cv;using namespace cv::superres;static Ptr<DenseOpticalFlowExt> createOptFlow (string name) ;int main (int argc, char *argv[]) { string inputVideoName; string outputVideoName; if (argc > 1 ) inputVideoName = argv[1 ]; else inputVideoName = ".\\tree.avi" ; if (argc > 2 ) outputVideoName = argv[2 ]; else outputVideoName = ".\\tree_superresolution.avi" ; const int scale = 4 ; const int iterations = 180 ; const int temporalAreaRadius =4 ; string optFlow = "farneback" ; double outputFps = 25.0 ; Ptr<DenseOpticalFlowExt> optical_flow = createOptFlow (optFlow); if (optical_flow.empty ()) return -1 ; Ptr<SuperResolution> superRes; superRes = createSuperResolution_BTVL1 (); superRes->setOpticalFlow (optical_flow); superRes->setScale (scale); superRes->setIterations (iterations); superRes->setTemporalAreaRadius (temporalAreaRadius); Ptr<FrameSource> frameSource; frameSource = createFrameSource_Video (inputVideoName); superRes->setInput (frameSource); Mat frame; frameSource->nextFrame (frame); cout << "Input : " << inputVideoName << " " << frame.size () << endl; cout << "Output : " << outputVideoName << endl; cout << "Playback speed output : " << outputFps << endl; cout << "Scale factor : " << scale << endl; cout << "Iterations : " << iterations << endl; cout << "Temporal radius : " << temporalAreaRadius << endl; cout << "Optical Flow : " << optFlow << endl; cout << endl; VideoWriter writer; double start_time,finish_time; for (int i = 0 ;; ++i) { cout << '[' << setw (3 ) << i << "] : " ; Mat result; start_time = getTickCount (); superRes->nextFrame (result); finish_time = getTickCount (); cout << (finish_time - start_time)/getTickFrequency () << " secs, Size: " << result.size () << endl; if (result.empty ()) break ; imshow ("Super Resolution" , result); if (waitKey (1000 ) > 0 ) break ; if (!outputVideoName.empty ()) { if (!writer.isOpened ()) writer.open (outputVideoName, VideoWriter::fourcc ('X' , 'V' , 'I' , 'D' ), outputFps, result.size ()); writer << result; } } writer.release (); return 0 ; }static Ptr<DenseOpticalFlowExt> createOptFlow (string name) { if (name == "farneback" ) return createOptFlow_Farneback (); else if (name == "tvl1" ) return createOptFlow_DualTVL1 (); else if (name == "brox" ) return createOptFlow_Brox_CUDA (); else if (name == "pyrlk" ) return createOptFlow_PyrLK_CUDA (); else cerr << "Incorrect Optical Flow algorithm - " << name << endl; return Ptr <DenseOpticalFlowExt>(); }
用来测试的视频信息为
$ ffprobe test.avi ... Input Duration: 00:00:16.53, start: 0.000000, bitrate: 1292 kb/s Stream
原始视频为360p,30帧,时长为16秒
使用farneback模式进行放大,测试环境为戴尔G15 1511 i7-11800H 8核16线程,16G内存
测试程序输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 $ ./sr test.avi tsr.avi Input : test.avi [640 x 360] Output : tsr.avi Playback speed output : 25 Scale factor : 4 Iterations : 180 Temporal radius : 4 Optical Flow : farneback [ 0] : 543.328 secs, Size: [2546 x 1426] [ 1] : 86.5821 secs, Size: [2546 x 1426] [ 2] : 89.9619 secs, Size: [2546 x 1426] [ 3] : 89.7291 secs, Size: [2546 x 1426] [ 4] : 89.9414 secs, Size: [2546 x 1426] [ 5] : 90.3375 secs, Size: [2546 x 1426] [ 6] : 91.1083 secs, Size: [2546 x 1426] [ 7] : 91.6142 secs, Size: [2546 x 1426] [ 8] : 91.4761 secs, Size: [2546 x 1426] [ 9] : 91.6939 secs, Size: [2546 x 1426] [ 10] : 91.86 secs, Size: [2546 x 1426] [ 11] : 91.8984 secs, Size: [2546 x 1426] [ 12] : 91.7052 secs, Size: [2546 x 1426] [ 13] : 91.7788 secs, Size: [2546 x 1426] [ 14] : 91.6301 secs, Size: [2546 x 1426] [ 15] : 91.5122 secs, Size: [2546 x 1426] [ 16] : 90.6578 secs, Size: [2546 x 1426] [ 17] : 90.612 secs, Size: [2546 x 1426] [ 18] : 91.185 secs, Size: [2546 x 1426] ... [481] : 90.6462 secs, Size: [2546 x 1426] [482] : 90.534 secs, Size: [2546 x 1426] [483] : 90.8866 secs, Size: [2546 x 1426] [484] : 90.6648 secs, Size: [2546 x 1426] [485] : 96.7889 secs, Size: [2546 x 1426] [486] : 89.6735 secs, Size: [2546 x 1426] [487] : 77.6115 secs, Size: [2546 x 1426] [488] : 68.7781 secs, Size: [2546 x 1426] [489] : 61.9018 secs, Size: [2546 x 1426] [490] : 0.00274725 secs, Size: [2546 x 1426] [491] : 0.00269216 secs, Size: [2546 x 1426] [492] : 0.00278245 secs, Size: [2546 x 1426] [493] : 0.00277431 secs, Size: [2546 x 1426] [494] : 0.00338189 secs, Size: [2546 x 1426] [495] : 2.182e-06 secs, Size: [0 x 0]
从2022.04.29 20:19:22到2022.04.30 09:06:01耗时8个小时,期间CPU16核全满,内存接近全满,GPU未使用。
而且画质不太好,频繁出现花屏
输出的结果视频信息为:
$ ffprobe tsr.avi ... Input Metadata: software : Lavf58.76.100 Duration: 00:00:19.80, start: 0.000000, bitrate: 19202 kb/s Stream
结果为1426p,25帧,时长19秒
总结还是更现代化的好使一点