Skip to content

Commit ccd8374

Browse files
committed
Repeal revert of BVLC#1878
1 parent 06ceaf4 commit ccd8374

File tree

7 files changed

+72
-95
lines changed

7 files changed

+72
-95
lines changed

include/caffe/util/io.hpp

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ inline bool ReadFileToDatum(const string& filename, Datum* datum) {
9292
}
9393

9494
bool ReadImageToDatum(const string& filename, const int label,
95-
const int height, const int width, const bool is_color, Datum* datum);
95+
const int height, const int width, const bool is_color,
96+
const std::string & encoding, Datum* datum);
97+
98+
inline bool ReadImageToDatum(const string& filename, const int label,
99+
const int height, const int width, const bool is_color, Datum* datum) {
100+
return ReadImageToDatum(filename, label, height, width, is_color,
101+
"", datum);
102+
}
96103

97104
inline bool ReadImageToDatum(const string& filename, const int label,
98105
const int height, const int width, Datum* datum) {
@@ -109,20 +116,12 @@ inline bool ReadImageToDatum(const string& filename, const int label,
109116
return ReadImageToDatum(filename, label, 0, 0, true, datum);
110117
}
111118

112-
bool DecodeDatum(const int height, const int width, const bool is_color,
113-
Datum* datum);
114-
115-
inline bool DecodeDatum(const int height, const int width, Datum* datum) {
116-
return DecodeDatum(height, width, true, datum);
117-
}
118-
119-
inline bool DecodeDatum(const bool is_color, Datum* datum) {
120-
return DecodeDatum(0, 0, is_color, datum);
119+
inline bool ReadImageToDatum(const string& filename, const int label,
120+
const std::string & encoding, Datum* datum) {
121+
return ReadImageToDatum(filename, label, 0, 0, true, encoding, datum);
121122
}
122123

123-
inline bool DecodeDatum(Datum* datum) {
124-
return DecodeDatum(0, 0, true, datum);
125-
}
124+
bool DecodeDatumNative(Datum* datum);
126125

127126
cv::Mat ReadImageToCVMat(const string& filename,
128127
const int height, const int width, const bool is_color);
@@ -135,16 +134,7 @@ cv::Mat ReadImageToCVMat(const string& filename,
135134

136135
cv::Mat ReadImageToCVMat(const string& filename);
137136

138-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
139-
const int height, const int width, const bool is_color);
140-
141-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
142-
const int height, const int width);
143-
144-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
145-
const bool is_color);
146-
147-
cv::Mat DecodeDatumToCVMat(const Datum& datum);
137+
cv::Mat DecodeDatumToCVMatNative(const Datum& datum);
148138

149139
void CVMatToDatum(const cv::Mat& cv_img, Datum* datum);
150140

src/caffe/layers/data_layer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
4242
Datum datum;
4343
datum.ParseFromString(cursor_->value());
4444

45-
if (DecodeDatum(&datum)) {
45+
if (DecodeDatumNative(&datum)) {
4646
LOG(INFO) << "Decoding Datum";
4747
}
4848
// image
@@ -110,7 +110,7 @@ void DataLayer<Dtype>::InternalThreadEntry() {
110110

111111
cv::Mat cv_img;
112112
if (datum.encoded()) {
113-
cv_img = DecodeDatumToCVMat(datum);
113+
cv_img = DecodeDatumToCVMatNative(datum);
114114
}
115115
read_time += timer.MicroSeconds();
116116
timer.Start();

src/caffe/layers/window_data_layer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ void WindowDataLayer<Dtype>::InternalThreadEntry() {
278278
if (this->cache_images_) {
279279
pair<std::string, Datum> image_cached =
280280
image_database_cache_[window[WindowDataLayer<Dtype>::IMAGE_INDEX]];
281-
cv_img = DecodeDatumToCVMat(image_cached.second);
281+
cv_img = DecodeDatumToCVMatNative(image_cached.second);
282282
} else {
283283
cv_img = cv::imread(image.first, CV_LOAD_IMAGE_COLOR);
284284
if (!cv_img.data) {

src/caffe/test/test_io.cpp

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ TEST_F(IOTest, TestDecodeDatum) {
289289
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
290290
Datum datum;
291291
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
292-
EXPECT_TRUE(DecodeDatum(&datum));
293-
EXPECT_FALSE(DecodeDatum(&datum));
292+
EXPECT_TRUE(DecodeDatumNative(&datum));
293+
EXPECT_FALSE(DecodeDatumNative(&datum));
294294
Datum datum_ref;
295295
ReadImageToDatumReference(filename, 0, 0, 0, true, &datum_ref);
296296
EXPECT_EQ(datum.channels(), datum_ref.channels());
@@ -309,38 +309,17 @@ TEST_F(IOTest, TestDecodeDatumToCVMat) {
309309
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
310310
Datum datum;
311311
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
312-
cv::Mat cv_img = DecodeDatumToCVMat(datum);
312+
cv::Mat cv_img = DecodeDatumToCVMatNative(datum);
313313
EXPECT_EQ(cv_img.channels(), 3);
314314
EXPECT_EQ(cv_img.rows, 360);
315315
EXPECT_EQ(cv_img.cols, 480);
316316
}
317317

318-
TEST_F(IOTest, TestDecodeDatumToCVMatResized) {
319-
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
320-
Datum datum;
321-
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
322-
cv::Mat cv_img = DecodeDatumToCVMat(datum, 100, 200);
323-
EXPECT_EQ(cv_img.channels(), 3);
324-
EXPECT_EQ(cv_img.rows, 100);
325-
EXPECT_EQ(cv_img.cols, 200);
326-
}
327-
328-
TEST_F(IOTest, TestDecodeDatumToCVMatResizedGray) {
329-
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
330-
Datum datum;
331-
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
332-
const bool is_color = false;
333-
cv::Mat cv_img = DecodeDatumToCVMat(datum, 200, 100, is_color);
334-
EXPECT_EQ(cv_img.channels(), 1);
335-
EXPECT_EQ(cv_img.rows, 200);
336-
EXPECT_EQ(cv_img.cols, 100);
337-
}
338-
339318
TEST_F(IOTest, TestDecodeDatumToCVMatContent) {
340319
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
341320
Datum datum;
342-
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
343-
cv::Mat cv_img = DecodeDatumToCVMat(datum);
321+
EXPECT_TRUE(ReadImageToDatum(filename, 0, std::string("jpg"), &datum));
322+
cv::Mat cv_img = DecodeDatumToCVMatNative(datum);
344323
cv::Mat cv_img_ref = ReadImageToCVMat(filename);
345324
EXPECT_EQ(cv_img_ref.channels(), cv_img.channels());
346325
EXPECT_EQ(cv_img_ref.rows, cv_img.rows);

src/caffe/util/io.cpp

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,36 @@ cv::Mat ReadImageToCVMat(const string& filename,
9898
cv::Mat ReadImageToCVMat(const string& filename) {
9999
return ReadImageToCVMat(filename, 0, 0, true);
100100
}
101-
101+
// Do the file extension and encoding match?
102+
static bool matchExt(const std::string & fn,
103+
std::string en) {
104+
size_t p = fn.rfind('.');
105+
std::string ext = p != fn.npos ? fn.substr(p) : fn;
106+
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
107+
std::transform(en.begin(), en.end(), en.begin(), ::tolower);
108+
if ( ext == en )
109+
return true;
110+
if ( en == "jpg" && ext == "jpeg" )
111+
return true;
112+
return false;
113+
}
102114
bool ReadImageToDatum(const string& filename, const int label,
103-
const int height, const int width, const bool is_color, Datum* datum) {
115+
const int height, const int width, const bool is_color,
116+
const std::string & encoding, Datum* datum) {
104117
cv::Mat cv_img = ReadImageToCVMat(filename, height, width, is_color);
105118
if (cv_img.data) {
119+
if (encoding.size()) {
120+
if ( (cv_img.channels() == 3) == is_color && !height && !width &&
121+
matchExt(filename, encoding) )
122+
return ReadFileToDatum(filename, label, datum);
123+
std::vector<uchar> buf;
124+
cv::imencode("."+encoding, cv_img, buf);
125+
datum->set_data(std::string(reinterpret_cast<char*>(&buf[0]),
126+
buf.size()));
127+
datum->set_label(label);
128+
datum->set_encoded(true);
129+
return true;
130+
}
106131
CVMatToDatum(cv_img, datum);
107132
datum->set_label(label);
108133
return true;
@@ -131,47 +156,24 @@ bool ReadFileToDatum(const string& filename, const int label,
131156
}
132157
}
133158

134-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
135-
const int height, const int width, const bool is_color) {
159+
cv::Mat DecodeDatumToCVMatNative(const Datum& datum) {
136160
cv::Mat cv_img;
137161
CHECK(datum.encoded()) << "Datum not encoded";
138-
int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
139-
CV_LOAD_IMAGE_GRAYSCALE);
140162
const string& data = datum.data();
141163
std::vector<char> vec_data(data.c_str(), data.c_str() + data.size());
142-
if (height > 0 && width > 0) {
143-
cv::Mat cv_img_origin = cv::imdecode(cv::Mat(vec_data), cv_read_flag);
144-
cv::resize(cv_img_origin, cv_img, cv::Size(width, height));
145-
} else {
146-
cv_img = cv::imdecode(vec_data, cv_read_flag);
147-
}
164+
cv_img = cv::imdecode(vec_data, -1);
148165
if (!cv_img.data) {
149166
LOG(ERROR) << "Could not decode datum ";
150167
}
151168
return cv_img;
152169
}
153170

154-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
155-
const int height, const int width) {
156-
return DecodeDatumToCVMat(datum, height, width, true);
157-
}
158-
159-
cv::Mat DecodeDatumToCVMat(const Datum& datum,
160-
const bool is_color) {
161-
return DecodeDatumToCVMat(datum, 0, 0, is_color);
162-
}
163-
164-
cv::Mat DecodeDatumToCVMat(const Datum& datum) {
165-
return DecodeDatumToCVMat(datum, 0, 0, true);
166-
}
167-
168171
// If Datum is encoded will decoded using DecodeDatumToCVMat and CVMatToDatum
169172
// if height and width are set it will resize it
170173
// If Datum is not encoded will do nothing
171-
bool DecodeDatum(const int height, const int width, const bool is_color,
172-
Datum* datum) {
174+
bool DecodeDatumNative(Datum* datum) {
173175
if (datum->encoded()) {
174-
cv::Mat cv_img = DecodeDatumToCVMat((*datum), height, width, is_color);
176+
cv::Mat cv_img = DecodeDatumToCVMatNative((*datum));
175177
CVMatToDatum(cv_img, datum);
176178
return true;
177179
} else {

tools/compute_image_mean.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ int main(int argc, char** argv) {
5050
Datum datum;
5151
datum.ParseFromString(cursor->value());
5252

53-
if (DecodeDatum(&datum)) {
53+
if (DecodeDatumNative(&datum)) {
5454
LOG(INFO) << "Decoding Datum";
5555
}
5656

@@ -68,7 +68,7 @@ int main(int argc, char** argv) {
6868
while (cursor->valid()) {
6969
Datum datum;
7070
datum.ParseFromString(cursor->value());
71-
DecodeDatum(&datum);
71+
DecodeDatumNative(&datum);
7272

7373
const std::string& data = datum.data();
7474
size_in_datum = std::max<int>(datum.data().size(),

tools/convert_imageset.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ DEFINE_bool(check_size, false,
3939
"When this option is on, check that all the datum have the same size");
4040
DEFINE_bool(encoded, false,
4141
"When this option is on, the encoded image will be save in datum");
42+
DEFINE_string(encode_type, "",
43+
"Optional: What type should we encode the image as ('png','jpg',...).");
4244

4345
int main(int argc, char** argv) {
4446
::google::InitGoogleLogging(argv[0]);
@@ -63,6 +65,7 @@ int main(int argc, char** argv) {
6365
const bool is_color = !FLAGS_gray;
6466
const bool check_size = FLAGS_check_size;
6567
const bool encoded = FLAGS_encoded;
68+
const string encode_type = FLAGS_encode_type;
6669

6770
std::ifstream infile(argv[2]);
6871
std::vector<std::pair<std::string, int> > lines;
@@ -78,11 +81,8 @@ int main(int argc, char** argv) {
7881
}
7982
LOG(INFO) << "A total of " << lines.size() << " images.";
8083

81-
if (encoded) {
82-
CHECK_EQ(FLAGS_resize_height, 0) << "With encoded don't resize images";
83-
CHECK_EQ(FLAGS_resize_width, 0) << "With encoded don't resize images";
84-
CHECK(!check_size) << "With encoded cannot check_size";
85-
}
84+
if (encode_type.size() && !encoded)
85+
LOG(INFO) << "encode_type specified, assuming encoded=true.";
8686

8787
int resize_height = std::max<int>(0, FLAGS_resize_height);
8888
int resize_width = std::max<int>(0, FLAGS_resize_width);
@@ -98,18 +98,24 @@ int main(int argc, char** argv) {
9898
int count = 0;
9999
const int kMaxKeyLength = 256;
100100
char key_cstr[kMaxKeyLength];
101-
int data_size;
101+
int data_size = 0;
102102
bool data_size_initialized = false;
103103

104104
for (int line_id = 0; line_id < lines.size(); ++line_id) {
105105
bool status;
106-
if (encoded) {
107-
status = ReadFileToDatum(root_folder + lines[line_id].first,
108-
lines[line_id].second, &datum);
109-
} else {
110-
status = ReadImageToDatum(root_folder + lines[line_id].first,
111-
lines[line_id].second, resize_height, resize_width, is_color, &datum);
106+
std::string enc = encode_type;
107+
if (encoded && !enc.size()) {
108+
// Guess the encoding type from the file name
109+
string fn = lines[line_id].first;
110+
size_t p = fn.rfind('.');
111+
if ( p == fn.npos )
112+
LOG(WARNING) << "Failed to guess the encoding of '" << fn << "'";
113+
enc = fn.substr(p);
114+
std::transform(enc.begin(), enc.end(), enc.begin(), ::tolower);
112115
}
116+
status = ReadImageToDatum(root_folder + lines[line_id].first,
117+
lines[line_id].second, resize_height, resize_width, is_color,
118+
enc, &datum);
113119
if (status == false) continue;
114120
if (check_size) {
115121
if (!data_size_initialized) {

0 commit comments

Comments
 (0)