Datum datum;
datum.ParseFromString(cursor_->value());
- if (DecodeDatumNative(&datum)) {
+ bool force_color = this->layer_param_.data_param().force_encoded_color();
+ if ((force_color && DecodeDatum(&datum, true)) ||
+ DecodeDatumNative(&datum)) {
LOG(INFO) << "Decoding Datum";
}
// image
top_label = this->prefetch_label_.mutable_cpu_data();
}
const int batch_size = this->layer_param_.data_param().batch_size();
+ bool force_color = this->layer_param_.data_param().force_encoded_color();
for (int item_id = 0; item_id < batch_size; ++item_id) {
timer.Start();
// get a blob
cv::Mat cv_img;
if (datum.encoded()) {
- cv_img = DecodeDatumToCVMatNative(datum);
+ if (force_color)
+ cv_img = DecodeDatumToCVMat(datum, true);
+ else
+ cv_img = DecodeDatumToCVMatNative(datum);
+ if (cv_img.channels() != this->transformed_data_.channels())
+ LOG(WARNING) << "Your dataset contains encoded images with mixed "
+ << "channel sizes. Consider adding a 'force_color' flag to the "
+ << "model definition, or rebuild your dataset using "
+ << "convert_imageset.";
}
read_time += timer.MicroSeconds();
timer.Start();
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
Datum datum;
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
+ EXPECT_TRUE(DecodeDatum(&datum, true));
+ EXPECT_FALSE(DecodeDatum(&datum, true));
+ Datum datum_ref;
+ ReadImageToDatumReference(filename, 0, 0, 0, true, &datum_ref);
+ EXPECT_EQ(datum.channels(), datum_ref.channels());
+ EXPECT_EQ(datum.height(), datum_ref.height());
+ EXPECT_EQ(datum.width(), datum_ref.width());
+ EXPECT_EQ(datum.data().size(), datum_ref.data().size());
+
+ const string& data = datum.data();
+ const string& data_ref = datum_ref.data();
+ for (int i = 0; i < datum.data().size(); ++i) {
+ EXPECT_TRUE(data[i] == data_ref[i]);
+ }
+}
+
+TEST_F(IOTest, TestDecodeDatumToCVMat) {
+ string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
+ Datum datum;
+ EXPECT_TRUE(ReadFileToDatum(filename, &datum));
+ cv::Mat cv_img = DecodeDatumToCVMat(datum, true);
+ EXPECT_EQ(cv_img.channels(), 3);
+ EXPECT_EQ(cv_img.rows, 360);
+ EXPECT_EQ(cv_img.cols, 480);
+ cv_img = DecodeDatumToCVMat(datum, false);
+ EXPECT_EQ(cv_img.channels(), 1);
+ EXPECT_EQ(cv_img.rows, 360);
+ EXPECT_EQ(cv_img.cols, 480);
+}
+
+TEST_F(IOTest, TestDecodeDatumToCVMatContent) {
+ string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
+ Datum datum;
+ EXPECT_TRUE(ReadImageToDatum(filename, 0, std::string("jpg"), &datum));
+ cv::Mat cv_img = DecodeDatumToCVMat(datum, true);
+ cv::Mat cv_img_ref = ReadImageToCVMat(filename);
+ EXPECT_EQ(cv_img_ref.channels(), cv_img.channels());
+ EXPECT_EQ(cv_img_ref.rows, cv_img.rows);
+ EXPECT_EQ(cv_img_ref.cols, cv_img.cols);
+
+ for (int c = 0; c < datum.channels(); ++c) {
+ for (int h = 0; h < datum.height(); ++h) {
+ for (int w = 0; w < datum.width(); ++w) {
+ EXPECT_TRUE(cv_img.at<cv::Vec3b>(h, w)[c]==
+ cv_img_ref.at<cv::Vec3b>(h, w)[c]);
+ }
+ }
+ }
+}
+
+TEST_F(IOTest, TestDecodeDatumNative) {
+ string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
+ Datum datum;
+ EXPECT_TRUE(ReadFileToDatum(filename, &datum));
EXPECT_TRUE(DecodeDatumNative(&datum));
EXPECT_FALSE(DecodeDatumNative(&datum));
Datum datum_ref;
}
}
-TEST_F(IOTest, TestDecodeDatumToCVMat) {
+TEST_F(IOTest, TestDecodeDatumToCVMatNative) {
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
Datum datum;
EXPECT_TRUE(ReadFileToDatum(filename, &datum));
EXPECT_EQ(cv_img.cols, 480);
}
-TEST_F(IOTest, TestDecodeDatumToCVMatContent) {
+TEST_F(IOTest, TestDecodeDatumNativeGray) {
+ string filename = EXAMPLES_SOURCE_DIR "images/cat_gray.jpg";
+ Datum datum;
+ EXPECT_TRUE(ReadFileToDatum(filename, &datum));
+ EXPECT_TRUE(DecodeDatumNative(&datum));
+ EXPECT_FALSE(DecodeDatumNative(&datum));
+ Datum datum_ref;
+ ReadImageToDatumReference(filename, 0, 0, 0, false, &datum_ref);
+ EXPECT_EQ(datum.channels(), datum_ref.channels());
+ EXPECT_EQ(datum.height(), datum_ref.height());
+ EXPECT_EQ(datum.width(), datum_ref.width());
+ EXPECT_EQ(datum.data().size(), datum_ref.data().size());
+
+ const string& data = datum.data();
+ const string& data_ref = datum_ref.data();
+ for (int i = 0; i < datum.data().size(); ++i) {
+ EXPECT_TRUE(data[i] == data_ref[i]);
+ }
+}
+
+TEST_F(IOTest, TestDecodeDatumToCVMatNativeGray) {
+ string filename = EXAMPLES_SOURCE_DIR "images/cat_gray.jpg";
+ Datum datum;
+ EXPECT_TRUE(ReadFileToDatum(filename, &datum));
+ cv::Mat cv_img = DecodeDatumToCVMatNative(datum);
+ EXPECT_EQ(cv_img.channels(), 1);
+ EXPECT_EQ(cv_img.rows, 360);
+ EXPECT_EQ(cv_img.cols, 480);
+}
+
+TEST_F(IOTest, TestDecodeDatumToCVMatContentNative) {
string filename = EXAMPLES_SOURCE_DIR "images/cat.jpg";
Datum datum;
EXPECT_TRUE(ReadImageToDatum(filename, 0, std::string("jpg"), &datum));
}
return cv_img;
}
+cv::Mat DecodeDatumToCVMat(const Datum& datum, bool is_color) {
+ cv::Mat cv_img;
+ CHECK(datum.encoded()) << "Datum not encoded";
+ const string& data = datum.data();
+ std::vector<char> vec_data(data.c_str(), data.c_str() + data.size());
+ int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
+ CV_LOAD_IMAGE_GRAYSCALE);
+ cv_img = cv::imdecode(vec_data, cv_read_flag);
+ if (!cv_img.data) {
+ LOG(ERROR) << "Could not decode datum ";
+ }
+ return cv_img;
+}
// If Datum is encoded will decoded using DecodeDatumToCVMat and CVMatToDatum
-// if height and width are set it will resize it
// If Datum is not encoded will do nothing
bool DecodeDatumNative(Datum* datum) {
if (datum->encoded()) {
return false;
}
}
+bool DecodeDatum(Datum* datum, bool is_color) {
+ if (datum->encoded()) {
+ cv::Mat cv_img = DecodeDatumToCVMat((*datum), is_color);
+ CVMatToDatum(cv_img, datum);
+ return true;
+ } else {
+ return false;
+ }
+}
void CVMatToDatum(const cv::Mat& cv_img, Datum* datum) {
CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte";