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