Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/Colorization/colorizeVideo.cpp
3119 views
1
// This code is written by Sunita Nayak at BigVision LLC. It is based on the OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in this distribution and at http://opencv.org/license.html
3
4
// Usage example: ./colorizeVideo.out greyscaleVideo.mp4
5
6
#include <opencv2/dnn.hpp>
7
#include <opencv2/imgproc.hpp>
8
#include <opencv2/highgui.hpp>
9
#include <iostream>
10
11
using namespace cv;
12
using namespace cv::dnn;
13
using namespace std;
14
15
// the 313 ab cluster centers from pts_in_hull.npy (already transposed)
16
static float hull_pts[] = {
17
-90., -90., -90., -90., -90., -80., -80., -80., -80., -80., -80., -80., -80., -70., -70., -70., -70., -70., -70., -70., -70.,
18
-70., -70., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -50., -50., -50., -50., -50., -50., -50., -50.,
19
-50., -50., -50., -50., -50., -50., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -30.,
20
-30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -30., -20., -20., -20., -20., -20., -20., -20.,
21
-20., -20., -20., -20., -20., -20., -20., -20., -20., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10., -10.,
22
-10., -10., -10., -10., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 10., 10., 10., 10., 10., 10., 10.,
23
10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20.,
24
20., 20., 20., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 40., 40., 40., 40.,
25
40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 40., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50.,
26
50., 50., 50., 50., 50., 50., 50., 50., 50., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60., 60.,
27
60., 60., 60., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 70., 80., 80., 80.,
28
80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 80., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90.,
29
90., 90., 90., 90., 90., 90., 90., 90., 90., 100., 100., 100., 100., 100., 100., 100., 100., 100., 100., 50., 60., 70., 80., 90.,
30
20., 30., 40., 50., 60., 70., 80., 90., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -20., -10., 0., 10., 20., 30., 40., 50.,
31
60., 70., 80., 90., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -40., -30., -20., -10., 0., 10., 20.,
32
30., 40., 50., 60., 70., 80., 90., 100., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -50.,
33
-40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., -60., -50., -40., -30., -20., -10., 0., 10., 20.,
34
30., 40., 50., 60., 70., 80., 90., 100., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90.,
35
100., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -80., -70., -60., -50.,
36
-40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -90., -80., -70., -60., -50., -40., -30., -20., -10.,
37
0., 10., 20., 30., 40., 50., 60., 70., 80., 90., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30.,
38
40., 50., 60., 70., 80., 90., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70.,
39
80., -110., -100., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., -110., -100.,
40
-90., -80., -70., -60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., 80., -110., -100., -90., -80., -70.,
41
-60., -50., -40., -30., -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., -110., -100., -90., -80., -70., -60., -50., -40., -30.,
42
-20., -10., 0., 10., 20., 30., 40., 50., 60., 70., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0.
43
};
44
45
int main(int argc, char **argv)
46
{
47
48
string videoFileName;
49
string device;
50
51
// Take arguments from command line
52
if (argc == 3)
53
{
54
device = argv[2];
55
}
56
else if (argc == 2)
57
device = "cpu";
58
else
59
{
60
cout << "Please input the greyscale video filename." << endl;
61
cout << "Usage example: ./colorizeVideo.out greyscaleVideo.mp4" << endl;
62
cout << "If you want to use GPU device instead of CPU, add one more argument." << endl;
63
cout << "Usage example: ./colorizeVideo.out greyscaleVideo.mp4 gpu" << endl;
64
return 1;
65
}
66
videoFileName = argv[1];
67
68
cv::VideoCapture cap(videoFileName);
69
if (!cap.isOpened())
70
{
71
cerr << "Unable to open video" << endl;
72
return 1;
73
}
74
75
cout << "Input video file: " << videoFileName << endl;
76
77
string protoFile = "./models/colorization_deploy_v2.prototxt";
78
string weightsFile = "./models/colorization_release_v2.caffemodel";
79
80
Mat frame, frameCopy;
81
int frameWidth = cap.get(CAP_PROP_FRAME_WIDTH);
82
int frameHeight = cap.get(CAP_PROP_FRAME_HEIGHT);
83
84
string str = videoFileName;
85
str.replace(str.end() - 4, str.end(), "");
86
string outVideoFileName = str + "_colorized.avi";
87
VideoWriter video(outVideoFileName, VideoWriter::fourcc('M','J','P','G'), 60, Size(frameWidth,frameHeight));
88
89
// fixed input size for the pre-trained network
90
const int W_in = 224;
91
const int H_in = 224;
92
Net net = dnn::readNetFromCaffe(protoFile, weightsFile);
93
if (device != "gpu")
94
{
95
cout << "Using CPU device" << endl;
96
net.setPreferableBackend(DNN_TARGET_CPU);
97
}
98
else
99
{
100
cout << "Using GPU device" << endl;
101
net.setPreferableBackend(DNN_BACKEND_CUDA);
102
net.setPreferableTarget(DNN_TARGET_CUDA);
103
}
104
105
// setup additional layers:
106
int sz[] = {2, 313, 1, 1};
107
const Mat pts_in_hull(4, sz, CV_32F, hull_pts);
108
Ptr<dnn::Layer> class8_ab = net.getLayer("class8_ab");
109
class8_ab->blobs.push_back(pts_in_hull);
110
Ptr<dnn::Layer> conv8_313_rh = net.getLayer("conv8_313_rh");
111
conv8_313_rh->blobs.push_back(Mat(1, 313, CV_32F, Scalar(2.606)));
112
113
vector<float> timer;
114
115
for(;;)
116
{
117
118
cap >> frame;
119
if (frame.empty()) break;
120
121
frameCopy = frame.clone();
122
123
double t = (double) cv::getTickCount();
124
125
// extract L channel and subtract mean
126
Mat lab, L, input;
127
frame.convertTo(frame, CV_32F, 1.0/255);
128
cvtColor(frame, lab, COLOR_BGR2Lab);
129
extractChannel(lab, L, 0);
130
resize(L, input, Size(W_in, H_in));
131
input -= 50;
132
133
// run the L channel through the network
134
Mat inputBlob = blobFromImage(input);
135
net.setInput(inputBlob);
136
Mat result = net.forward();
137
138
// retrieve the calculated a,b channels from the network output
139
Size out_size(result.size[2], result.size[3]);
140
Mat a = Mat(out_size, CV_32F, result.ptr(0, 0));
141
Mat b = Mat(out_size, CV_32F, result.ptr(0, 1));
142
143
resize(a, a, frame.size());
144
resize(b, b, frame.size());
145
146
// merge, and convert back to BGR
147
Mat coloredFrame, chn[] = {L, a, b};
148
merge(chn, 3, lab);
149
cvtColor(lab, coloredFrame, COLOR_Lab2BGR);
150
151
t = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
152
timer.push_back(t);
153
154
coloredFrame = coloredFrame.mul(255);
155
coloredFrame.convertTo(coloredFrame, CV_8U);
156
video.write(coloredFrame);
157
158
}
159
160
cout << "Time taken : " << accumulate(timer.begin(), timer.end(), 0.0) << " secs" << endl;
161
cout << "Colorized video saved as " << outVideoFileName << endl << "Done !!!" << endl;
162
cap.release();
163
video.release();
164
165
return 0;
166
}
167
168