blob: cc22ada8702916a1571c9a2b31f56dc21a9e79af [file] [log] [blame]
/************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include <time.h>
#include <iostream>
#include "gtest/gtest.h"
#include "singa/io/transformer.h"
// decide whether to use opencv
// #include "singa/singa_config.h"
#ifdef USE_OPENCV
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#endif
using singa::Shape;
TEST(ImageTransformer, Setup) {
singa::ImageTransformer img_transformer;
singa::TransformerConf conf;
conf.set_resize_height(256);
conf.set_resize_width(256);
conf.set_horizontal_mirror(true);
conf.set_image_dim_order("HWC");
conf.add_crop_shape(224u);
conf.add_crop_shape(200u);
img_transformer.Setup(conf);
EXPECT_EQ(256, img_transformer.resize_height());
EXPECT_EQ(256, img_transformer.resize_width());
EXPECT_EQ(true, img_transformer.horizontal_mirror());
EXPECT_EQ("HWC", img_transformer.image_dim_order());
EXPECT_EQ(224u, img_transformer.crop_shape()[0]);
EXPECT_EQ(200u, img_transformer.crop_shape()[1]);
}
TEST(ImageTransformer, Apply3D) {
size_t n = 180;
float* x = new float[n];
size_t channel = 3, height = 6, width = 10;
singa::Tensor in(singa::Shape{height, width, channel});
srand((unsigned int)time(NULL));
for (size_t i = 0; i < n; i++) x[i] = (float)(rand() % 256);
in.CopyDataFromHostPtr<float>(x, n);
int resize_height = 4, resize_width = 6;
singa::ImageTransformer img_transformer;
singa::TransformerConf conf;
conf.set_resize_height(resize_height);
conf.set_resize_width(resize_width);
conf.set_horizontal_mirror(false);
conf.set_image_dim_order("HWC");
conf.add_crop_shape(2u);
conf.add_crop_shape(3u);
img_transformer.Setup(conf);
singa::Tensor out = img_transformer.Apply(singa::kEval, in);
EXPECT_EQ(2u, out.shape(0));
EXPECT_EQ(3u, out.shape(1));
const float* y = out.data<float>();
#ifdef USE_OPENCV
cv::Mat mat(height, width, CV_32FC3, cv::Scalar(0, 0, 0));
for (size_t i = 0; i < height; i++)
for (size_t j = 0; j < width; j++)
for (size_t k = 0; k < channel; k++)
mat.at<cv::Vec3f>(i, j)[k] = x[i * width * channel + j * channel + k];
cv::Size size(resize_width, resize_height);
cv::Mat resized;
cv::resize(mat, resized, size);
EXPECT_EQ(resize_height, resized.size().height);
EXPECT_EQ(resize_width, resized.size().width);
size_t new_size = resize_height * resize_width * channel;
float* xt = new float[new_size];
for (int i = 0; i < resize_height; i++)
for (int j = 0; j < resize_width; j++)
for (size_t k = 0; k < channel; k++)
xt[i * resize_width * channel + j * channel + k] =
resized.at<cv::Vec3f>(i, j)[k];
for (size_t c = 0; c < 3; c++)
for (size_t h = 0; h < 2; h++)
for (size_t w = 0; w < 3; w++) {
// size_t in_idx = (c * height + 1 + h) * width + 1 + w,
// out_idx = (c * 2 + h) * 3 + w;
// test for HWC
size_t in_idx = ((h + 1) * resize_width + 1 + w) * channel + c,
out_idx = (h * 3 + w) * channel + c;
EXPECT_EQ(xt[in_idx], y[out_idx]);
}
delete[] xt;
#else
for (size_t c = 0; c < 3; c++)
for (size_t h = 0; h < 2; h++)
for (size_t w = 0; w < 3; w++) {
// size_t in_idx = (c * height + 2 + h) * width + 3 + w,
// out_idx = (c * 2 + h) * 3 + w;
// test for HWC
size_t in_idx = ((h + 2) * width + 3 + w) * channel + c,
out_idx = (h * 3 + w) * channel + c;
EXPECT_EQ(x[in_idx], y[out_idx]);
}
#endif
delete[] x;
}
TEST(ImageTransformer, Apply2D) {
size_t n = 60;
float* x = new float[n];
size_t height = 6, width = 10;
singa::Tensor in(singa::Shape{height, width});
srand((unsigned int)time(NULL));
for (size_t i = 0; i < n; i++) x[i] = (float)(rand() % 256);
in.CopyDataFromHostPtr<float>(x, n);
int resize_height = 4, resize_width = 6;
singa::ImageTransformer img_transformer;
singa::TransformerConf conf;
conf.set_resize_height(resize_height);
conf.set_resize_width(resize_width);
conf.set_horizontal_mirror(false);
conf.set_image_dim_order("HWC");
conf.add_crop_shape(2u);
conf.add_crop_shape(3u);
img_transformer.Setup(conf);
singa::Tensor out = img_transformer.Apply(singa::kEval, in);
EXPECT_EQ(2u, out.shape(0));
EXPECT_EQ(3u, out.shape(1));
const float* y = out.data<float>();
#ifdef USE_OPENCV
cv::Mat mat(height, width, CV_32FC1, cv::Scalar(0, 0, 0));
for (size_t i = 0; i < height; i++)
for (size_t j = 0; j < width; j++)
mat.at<cv::Vec<float, 1>>(i, j)[0] = x[i * width + j];
cv::Size size(resize_width, resize_height);
cv::Mat resized;
cv::resize(mat, resized, size);
EXPECT_EQ(resize_height, resized.size().height);
EXPECT_EQ(resize_width, resized.size().width);
size_t new_size = resize_height * resize_width;
float* xt = new float[new_size];
for (int i = 0; i < resize_height; i++)
for (int j = 0; j < resize_width; j++)
xt[i * resize_width + j] = resized.at<cv::Vec<float, 1>>(i, j)[0];
for (size_t h = 0; h < 2; h++)
for (size_t w = 0; w < 3; w++) {
size_t in_idx = (h + 1) * resize_width + 1 + w, out_idx = h * 3 + w;
EXPECT_EQ(xt[in_idx], y[out_idx]);
}
delete[] xt;
#else
for (size_t h = 0; h < 2; h++)
for (size_t w = 0; w < 3; w++) {
size_t in_idx = (h + 2) * width + 3 + w, out_idx = h * 3 + w;
EXPECT_EQ(x[in_idx], y[out_idx]);
}
#endif
delete[] x;
}
#ifdef USE_OPENCV
TEST(ImageTransformer, Resize) {
size_t n = 180;
float* x = new float[n];
size_t channel = 3, height = 6, width = 10;
singa::Tensor in(singa::Shape{height, width, channel});
srand(time(NULL));
for (size_t i = 0; i < n; i++) x[i] = (float)(rand() % 256);
in.CopyDataFromHostPtr<float>(x, n);
int resize_height = 4, resize_width = 5;
singa::Tensor out = singa::resize(in, resize_height, resize_width, "HWC");
const float* y = out.data<float>();
cv::Mat mat(height, width, CV_32FC3, cv::Scalar(0, 0, 0));
for (size_t i = 0; i < height; i++)
for (size_t j = 0; j < width; j++)
for (size_t k = 0; k < channel; k++)
mat.at<cv::Vec3f>(i, j)[k] = x[i * width * channel + j * channel + k];
cv::Size size(resize_width, resize_height);
cv::Mat resized;
cv::resize(mat, resized, size);
EXPECT_EQ(resize_height, resized.size().height);
EXPECT_EQ(resize_width, resized.size().width);
size_t new_size = resize_height * resize_width * channel;
float* xt = new float[new_size];
for (int i = 0; i < resize_height; i++)
for (int j = 0; j < resize_width; j++)
for (size_t k = 0; k < channel; k++)
xt[i * resize_width * channel + j * channel + k] =
resized.at<cv::Vec3f>(i, j)[k];
for (size_t i = 0; i < new_size; i++) EXPECT_EQ(xt[i], y[i]);
delete[] x;
delete[] xt;
}
#endif
TEST(ImageTransformer, Crop) {
size_t n = 180;
float* x = new float[n];
size_t channel = 3, height = 6, width = 10;
singa::Tensor in(singa::Shape{channel, height, width});
srand((unsigned int)time(NULL));
for (size_t i = 0; i < n; i++) x[i] = (float)(rand() % 256);
in.CopyDataFromHostPtr<float>(x, n);
size_t crop_height = 3, crop_width = 4, crop_h_offset = 2, crop_w_offset = 5;
singa::Tensor out = singa::crop(in, crop_height, crop_width, crop_h_offset,
crop_w_offset, "CHW");
const float* y = out.data<float>();
for (size_t h = 0; h < crop_height; h++)
for (size_t w = 0; w < crop_width; w++)
for (size_t c = 0; c < channel; c++) {
size_t out_idx = c * crop_height * crop_width + h * crop_width + w;
size_t in_idx = c * height * width + (h + crop_h_offset) * width + w +
crop_w_offset;
EXPECT_EQ(x[in_idx], y[out_idx]);
}
delete[] x;
}
TEST(ImageTransformer, Mirror) {
size_t n = 30;
float* x = new float[n];
size_t channel = 3, height = 2, width = 5;
singa::Tensor in(singa::Shape{height, width, channel});
srand((unsigned int)time(NULL));
for (size_t i = 0; i < n; i++) x[i] = (float)(rand() % 256);
in.CopyDataFromHostPtr<float>(x, n);
singa::Tensor out = singa::mirror(in, true, false, "HWC");
const float* y = out.data<float>();
for (size_t h = 0; h < height; h++)
for (size_t w = 0; w < width; w++)
for (size_t c = 0; c < channel; c++) {
size_t out_idx = h * width * channel + (width - 1 - w) * channel + c;
size_t in_idx = h * width * channel + w * channel + c;
EXPECT_EQ(x[in_idx], y[out_idx]);
}
delete[] x;
}