From: @xiefangqi Reviewed-by: @liucunwei,@heleiwang Signed-off-by: @liucunweitags/v1.2.0-rc1
| @@ -174,6 +174,7 @@ Status BatchOp::BatchRows(const std::unique_ptr<TensorQTable> *src, const std::u | |||
| if (batch_size == 1) { | |||
| TensorRow row = std::move((*src)->front()); | |||
| row.setPath({}); | |||
| (*src)->pop_front(); | |||
| (*dest)->push_back(row); | |||
| for (const auto &tensor : (*dest)->front()) { | |||
| @@ -457,7 +457,7 @@ Status CifarOp::CountTotalRows(const std::string &dir, const std::string &usage, | |||
| for (auto &file : op->cifar_files_) { | |||
| Path file_path(file); | |||
| CHECK_FAIL_RETURN_UNEXPECTED(file_path.Exists() && !file_path.IsDirectory(), | |||
| "Invalid file, failed to open cifar file: " + file); | |||
| "Invalid file, failed to open cifar10 file: " + file); | |||
| std::string file_name = file_path.Basename(); | |||
| if (op->usage_ == "train") { | |||
| @@ -481,7 +481,7 @@ Status CifarOp::CountTotalRows(const std::string &dir, const std::string &usage, | |||
| std::string file_name = file_path.Basename(); | |||
| CHECK_FAIL_RETURN_UNEXPECTED(file_path.Exists() && !file_path.IsDirectory(), | |||
| "Invalid file, failed to find cifar file: " + file); | |||
| "Invalid file, failed to find cifar100 file: " + file); | |||
| if (op->usage_ == "train" && file_path.Basename().find("train") == std::string::npos) continue; | |||
| if (op->usage_ == "test" && file_path.Basename().find("test") == std::string::npos) continue; | |||
| @@ -425,9 +425,13 @@ Status CocoOp::SearchNodeInJson(const nlohmann::json &input_tree, std::string no | |||
| } | |||
| Status CocoOp::ParseAnnotationIds() { | |||
| std::ifstream in(annotation_path_); | |||
| nlohmann::json js; | |||
| in >> js; | |||
| try { | |||
| std::ifstream in(annotation_path_); | |||
| in >> js; | |||
| } catch (const std::exception &err) { | |||
| RETURN_STATUS_UNEXPECTED("Invalid file, failed to open json file: " + annotation_path_); | |||
| } | |||
| std::vector<std::string> image_que; | |||
| nlohmann::json image_list; | |||
| @@ -615,7 +619,7 @@ Status CocoOp::CategoriesColumnLoad(const nlohmann::json &categories_tree) { | |||
| if (task_type_ == TaskType::Panoptic) { | |||
| auto itr_isthing = category.find(kJsonCategoriesIsthing); | |||
| CHECK_FAIL_RETURN_UNEXPECTED(itr_isthing != category.end(), | |||
| "Invalid data, no isthing found in categories of " + annotation_path_); | |||
| "Invalid data, nothing found in categories of " + annotation_path_); | |||
| label_info.push_back(*itr_isthing); | |||
| } | |||
| label_index_.emplace_back(std::make_pair(name, label_info)); | |||
| @@ -19,7 +19,6 @@ | |||
| #include <fstream> | |||
| #include <iomanip> | |||
| #include "./tinyxml2.h" | |||
| #include "minddata/dataset/core/config_manager.h" | |||
| #include "minddata/dataset/core/tensor_shape.h" | |||
| #include "minddata/dataset/engine/datasetops/source/sampler/sequential_sampler.h" | |||
| @@ -28,9 +27,6 @@ | |||
| #include "minddata/dataset/engine/opt/pass.h" | |||
| #include "utils/ms_utils.h" | |||
| using tinyxml2::XMLDocument; | |||
| using tinyxml2::XMLElement; | |||
| using tinyxml2::XMLError; | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| const char kColumnImage[] = "image"; | |||
| @@ -327,6 +323,14 @@ Status VOCOp::ParseAnnotationIds() { | |||
| return Status::OK(); | |||
| } | |||
| void VOCOp::ParseNodeValue(XMLElement *bbox_node, const char *name, float *value) { | |||
| *value = 0.0; | |||
| if (bbox_node != nullptr) { | |||
| XMLElement *node = bbox_node->FirstChildElement(name); | |||
| if (node != nullptr) *value = node->FloatText(); | |||
| } | |||
| } | |||
| Status VOCOp::ParseAnnotationBbox(const std::string &path) { | |||
| if (!Path(path).Exists()) { | |||
| RETURN_STATUS_UNEXPECTED("Invalid file, failed to open file: " + path); | |||
| @@ -350,21 +354,15 @@ Status VOCOp::ParseAnnotationBbox(const std::string &path) { | |||
| float xmin = 0.0, ymin = 0.0, xmax = 0.0, ymax = 0.0, truncated = 0.0, difficult = 0.0; | |||
| XMLElement *name_node = object->FirstChildElement("name"); | |||
| if (name_node != nullptr && name_node->GetText() != 0) label_name = name_node->GetText(); | |||
| XMLElement *truncated_node = object->FirstChildElement("truncated"); | |||
| if (truncated_node != nullptr) truncated = truncated_node->FloatText(); | |||
| XMLElement *difficult_node = object->FirstChildElement("difficult"); | |||
| if (difficult_node != nullptr) difficult = difficult_node->FloatText(); | |||
| ParseNodeValue(object, "difficult", &difficult); | |||
| ParseNodeValue(object, "truncated", &truncated); | |||
| XMLElement *bbox_node = object->FirstChildElement("bndbox"); | |||
| if (bbox_node != nullptr) { | |||
| XMLElement *xmin_node = bbox_node->FirstChildElement("xmin"); | |||
| if (xmin_node != nullptr) xmin = xmin_node->FloatText(); | |||
| XMLElement *ymin_node = bbox_node->FirstChildElement("ymin"); | |||
| if (ymin_node != nullptr) ymin = ymin_node->FloatText(); | |||
| XMLElement *xmax_node = bbox_node->FirstChildElement("xmax"); | |||
| if (xmax_node != nullptr) xmax = xmax_node->FloatText(); | |||
| XMLElement *ymax_node = bbox_node->FirstChildElement("ymax"); | |||
| if (ymax_node != nullptr) ymax = ymax_node->FloatText(); | |||
| ParseNodeValue(bbox_node, "xmin", &xmin); | |||
| ParseNodeValue(bbox_node, "xmax", &xmax); | |||
| ParseNodeValue(bbox_node, "ymin", &ymin); | |||
| ParseNodeValue(bbox_node, "ymax", &ymax); | |||
| } else { | |||
| RETURN_STATUS_UNEXPECTED("Invalid data, bndbox dismatch in " + path); | |||
| } | |||
| @@ -406,7 +404,7 @@ Status VOCOp::ReadImageToTensor(const std::string &path, const ColDescriptor &co | |||
| if (decode_ == true) { | |||
| Status rc = Decode(*tensor, tensor); | |||
| if (rc.IsError()) { | |||
| RETURN_STATUS_UNEXPECTED("Invalid file, failed to decode file: " + path); | |||
| RETURN_STATUS_UNEXPECTED("Invalid data, failed to decode image: " + path); | |||
| } | |||
| } | |||
| return Status::OK(); | |||
| @@ -22,6 +22,7 @@ | |||
| #include <utility> | |||
| #include <vector> | |||
| #include "./tinyxml2.h" | |||
| #include "minddata/dataset/core/tensor.h" | |||
| #include "minddata/dataset/engine/data_buffer.h" | |||
| #include "minddata/dataset/engine/data_schema.h" | |||
| @@ -33,6 +34,9 @@ | |||
| #include "minddata/dataset/util/status.h" | |||
| #include "minddata/dataset/util/wait_post.h" | |||
| using tinyxml2::XMLDocument; | |||
| using tinyxml2::XMLElement; | |||
| using tinyxml2::XMLError; | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| // Forward declares | |||
| @@ -260,6 +264,12 @@ class VOCOp : public ParallelOp, public RandomAccessOp { | |||
| // @return Status The status code returned | |||
| Status ParseAnnotationBbox(const std::string &path); | |||
| // @param XMLElement *bbox_node - bbox node info found in json object | |||
| // @param const char *name - sub node name in object | |||
| // @param float *value - value of certain sub node | |||
| // @return Status The status code returned | |||
| void ParseNodeValue(XMLElement *bbox_node, const char *name, float *value); | |||
| // @param const std::shared_ptr<Tensor> &sample_ids - sample ids of tensor | |||
| // @param std::vector<int64_t> *keys - image id | |||
| // @return Status The status code returned | |||
| @@ -45,55 +45,59 @@ AffineOp::AffineOp(float_t degrees, const std::vector<float_t> &translation, flo | |||
| Status AffineOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) { | |||
| IO_CHECK(input, output); | |||
| float_t translation_x = translation_[0]; | |||
| float_t translation_y = translation_[1]; | |||
| float_t degrees = 0.0; | |||
| DegreesToRadians(degrees_, °rees); | |||
| float_t shear_x = shear_[0]; | |||
| float_t shear_y = shear_[1]; | |||
| DegreesToRadians(shear_x, &shear_x); | |||
| DegreesToRadians(-1 * shear_y, &shear_y); | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(input); | |||
| try { | |||
| float_t translation_x = translation_[0]; | |||
| float_t translation_y = translation_[1]; | |||
| float_t degrees = 0.0; | |||
| DegreesToRadians(degrees_, °rees); | |||
| float_t shear_x = shear_[0]; | |||
| float_t shear_y = shear_[1]; | |||
| DegreesToRadians(shear_x, &shear_x); | |||
| DegreesToRadians(-1 * shear_y, &shear_y); | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(input); | |||
| // Apply Affine Transformation | |||
| // T is translation matrix: [1, 0, tx | 0, 1, ty | 0, 0, 1] | |||
| // C is translation matrix to keep center: [1, 0, cx | 0, 1, cy | 0, 0, 1] | |||
| // RSS is rotation with scale and shear matrix | |||
| // RSS(a, s, (sx, sy)) = | |||
| // = R(a) * S(s) * SHy(sy) * SHx(sx) | |||
| // = [ s*cos(a - sy)/cos(sy), s*(-cos(a - sy)*tan(x)/cos(y) - sin(a)), 0 ] | |||
| // [ s*sin(a - sy)/cos(sy), s*(-sin(a - sy)*tan(x)/cos(y) + cos(a)), 0 ] | |||
| // [ 0 , 0 , 1 ] | |||
| // | |||
| // where R is a rotation matrix, S is a scaling matrix, and SHx and SHy are the shears: | |||
| // SHx(s) = [1, -tan(s)] and SHy(s) = [1 , 0] | |||
| // [0, 1 ] [-tan(s), 1] | |||
| // | |||
| // Thus, the affine matrix is M = T * C * RSS * C^-1 | |||
| // Apply Affine Transformation | |||
| // T is translation matrix: [1, 0, tx | 0, 1, ty | 0, 0, 1] | |||
| // C is translation matrix to keep center: [1, 0, cx | 0, 1, cy | 0, 0, 1] | |||
| // RSS is rotation with scale and shear matrix | |||
| // RSS(a, s, (sx, sy)) = | |||
| // = R(a) * S(s) * SHy(sy) * SHx(sx) | |||
| // = [ s*cos(a - sy)/cos(sy), s*(-cos(a - sy)*tan(x)/cos(y) - sin(a)), 0 ] | |||
| // [ s*sin(a - sy)/cos(sy), s*(-sin(a - sy)*tan(x)/cos(y) + cos(a)), 0 ] | |||
| // [ 0 , 0 , 1 ] | |||
| // | |||
| // where R is a rotation matrix, S is a scaling matrix, and SHx and SHy are the shears: | |||
| // SHx(s) = [1, -tan(s)] and SHy(s) = [1 , 0] | |||
| // [0, 1 ] [-tan(s), 1] | |||
| // | |||
| // Thus, the affine matrix is M = T * C * RSS * C^-1 | |||
| float_t cx = ((input_cv->mat().cols - 1) / 2.0); | |||
| float_t cy = ((input_cv->mat().rows - 1) / 2.0); | |||
| // Calculate RSS | |||
| std::vector<float_t> matrix{ | |||
| static_cast<float>(scale_ * cos(degrees + shear_y) / cos(shear_y)), | |||
| static_cast<float>(scale_ * (-1 * cos(degrees + shear_y) * tan(shear_x) / cos(shear_y) - sin(degrees))), | |||
| 0, | |||
| static_cast<float>(scale_ * sin(degrees + shear_y) / cos(shear_y)), | |||
| static_cast<float>(scale_ * (-1 * sin(degrees + shear_y) * tan(shear_x) / cos(shear_y) + cos(degrees))), | |||
| 0}; | |||
| // Compute T * C * RSS * C^-1 | |||
| matrix[2] = (1 - matrix[0]) * cx - matrix[1] * cy + translation_x; | |||
| matrix[5] = (1 - matrix[4]) * cy - matrix[3] * cx + translation_y; | |||
| cv::Mat affine_mat(matrix); | |||
| affine_mat = affine_mat.reshape(1, {2, 3}); | |||
| float_t cx = ((input_cv->mat().cols - 1) / 2.0); | |||
| float_t cy = ((input_cv->mat().rows - 1) / 2.0); | |||
| // Calculate RSS | |||
| std::vector<float_t> matrix{ | |||
| static_cast<float>(scale_ * cos(degrees + shear_y) / cos(shear_y)), | |||
| static_cast<float>(scale_ * (-1 * cos(degrees + shear_y) * tan(shear_x) / cos(shear_y) - sin(degrees))), | |||
| 0, | |||
| static_cast<float>(scale_ * sin(degrees + shear_y) / cos(shear_y)), | |||
| static_cast<float>(scale_ * (-1 * sin(degrees + shear_y) * tan(shear_x) / cos(shear_y) + cos(degrees))), | |||
| 0}; | |||
| // Compute T * C * RSS * C^-1 | |||
| matrix[2] = (1 - matrix[0]) * cx - matrix[1] * cy + translation_x; | |||
| matrix[5] = (1 - matrix[4]) * cy - matrix[3] * cx + translation_y; | |||
| cv::Mat affine_mat(matrix); | |||
| affine_mat = affine_mat.reshape(1, {2, 3}); | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| RETURN_UNEXPECTED_IF_NULL(output_cv); | |||
| cv::warpAffine(input_cv->mat(), output_cv->mat(), affine_mat, input_cv->mat().size(), | |||
| GetCVInterpolationMode(interpolation_), cv::BORDER_CONSTANT, | |||
| cv::Scalar(fill_value_[0], fill_value_[1], fill_value_[2])); | |||
| (*output) = std::static_pointer_cast<Tensor>(output_cv); | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| RETURN_UNEXPECTED_IF_NULL(output_cv); | |||
| cv::warpAffine(input_cv->mat(), output_cv->mat(), affine_mat, input_cv->mat().size(), | |||
| GetCVInterpolationMode(interpolation_), cv::BORDER_CONSTANT, | |||
| cv::Scalar(fill_value_[0], fill_value_[1], fill_value_[2])); | |||
| (*output) = std::static_pointer_cast<Tensor>(output_cv); | |||
| } catch (const cv::Exception &e) { | |||
| RETURN_STATUS_UNEXPECTED("Affine: " + std::string(e.what())); | |||
| } | |||
| return Status::OK(); | |||
| } | |||
| } // namespace dataset | |||
| @@ -48,7 +48,7 @@ Status BoundingBox::ValidateBoundingBoxes(const TensorRow &image_and_bbox) { | |||
| } | |||
| if (image_and_bbox[1]->shape().Size() < 2) { | |||
| return Status(StatusCode::kBoundingBoxInvalidShape, __LINE__, __FILE__, | |||
| "BoundingBox: bounding boxes shape should have at least two dimensions."); | |||
| "BoundingBox: bounding boxes should have to be two-dimensional matrix at least."); | |||
| } | |||
| uint32_t num_of_features = image_and_bbox[1]->shape()[1]; | |||
| if (num_of_features < 4) { | |||
| @@ -34,7 +34,7 @@ Status CenterCropOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_p | |||
| std::string err_msg; | |||
| std::string err_head = "CenterCrop: "; | |||
| dsize_t rank = input->shape().Rank(); | |||
| err_msg += (rank < 2 || rank > 3) ? "rank received::" + std::to_string(rank) + " Expected: 2 or 3 \t" : ""; | |||
| err_msg += (rank < 2 || rank > 3) ? "image shape is not <H,W,C> or <H,W> \t" : ""; | |||
| err_msg += (crop_het_ <= 0 || crop_wid_ <= 0) ? "crop size needs to be positive integers\t" : ""; | |||
| if (err_msg.length() != 0) RETURN_STATUS_UNEXPECTED(err_head + err_msg); | |||
| @@ -33,7 +33,7 @@ Status HwcToChwOp::OutputShape(const std::vector<TensorShape> &inputs, std::vect | |||
| TensorShape out = TensorShape{in[2], in[0], in[1]}; | |||
| if (inputs[0].Rank() == 3) outputs.emplace_back(out); | |||
| if (!outputs.empty()) return Status::OK(); | |||
| return Status(StatusCode::kUnexpectedError, "HwcToChw: invalid input shape."); | |||
| return Status(StatusCode::kUnexpectedError, "HWC2CHW: invalid input shape."); | |||
| } | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -61,6 +61,14 @@ int GetCVBorderType(BorderType type) { | |||
| } | |||
| } | |||
| bool CheckTensorShape(const std::shared_ptr<Tensor> &tensor, const int &channel) { | |||
| bool rc = false; | |||
| if (tensor->Rank() != 3 || (tensor->shape()[channel] != 1 && tensor->shape()[channel] != 3)) { | |||
| rc = true; | |||
| } | |||
| return rc; | |||
| } | |||
| Status Flip(std::shared_ptr<Tensor> input, std::shared_ptr<Tensor> *output, int flip_code) { | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(std::move(input)); | |||
| @@ -99,11 +107,13 @@ Status Resize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *out | |||
| } | |||
| cv::Mat in_image = input_cv->mat(); | |||
| // resize image too large or too small | |||
| if (output_height == 0 || output_height > in_image.rows * 1000 || output_width == 0 || | |||
| output_width > in_image.cols * 1000) { | |||
| if (output_height > in_image.rows * 1000 || output_width > in_image.cols * 1000) { | |||
| std::string err_msg = | |||
| "Resize: the resizing width or height 1) is too big, it's up to " | |||
| "1000 times the original image; 2) can not be 0."; | |||
| "Resize: the resizing width or height is too big, it's 1000 times bigger than the original image."; | |||
| return Status(StatusCode::kShapeMisMatch, err_msg); | |||
| } | |||
| if (output_height == 0 || output_width == 0) { | |||
| std::string err_msg = "Resize: the resizing width or height is invalid, width or height is zero."; | |||
| return Status(StatusCode::kShapeMisMatch, err_msg); | |||
| } | |||
| try { | |||
| @@ -216,7 +226,7 @@ static Status JpegReadScanlines(jpeg_decompress_struct *const cinfo, int max_sca | |||
| try { | |||
| num_lines_read = jpeg_read_scanlines(cinfo, &scanline_ptr, 1); | |||
| } catch (std::runtime_error &e) { | |||
| RETURN_STATUS_UNEXPECTED("Decode: jpeg_read_scanlines error."); | |||
| RETURN_STATUS_UNEXPECTED("Decode: image decode failed."); | |||
| } | |||
| if (cinfo->out_color_space == JCS_CMYK && num_lines_read > 0) { | |||
| for (int i = 0; i < crop_w; ++i) { | |||
| @@ -243,11 +253,11 @@ static Status JpegReadScanlines(jpeg_decompress_struct *const cinfo, int max_sca | |||
| int copy_status = memcpy_s(buffer, buffer_size, scanline_ptr + offset, stride); | |||
| if (copy_status != 0) { | |||
| jpeg_destroy_decompress(cinfo); | |||
| RETURN_STATUS_UNEXPECTED("Decode: memcpy failed"); | |||
| RETURN_STATUS_UNEXPECTED("Decode: memcpy failed."); | |||
| } | |||
| } else { | |||
| jpeg_destroy_decompress(cinfo); | |||
| std::string err_msg = "Decode: failed to read scanline"; | |||
| std::string err_msg = "Decode: image decode failed."; | |||
| RETURN_STATUS_UNEXPECTED(err_msg); | |||
| } | |||
| buffer += stride; | |||
| @@ -271,7 +281,7 @@ static Status JpegSetColorSpace(jpeg_decompress_struct *cinfo) { | |||
| return Status::OK(); | |||
| default: | |||
| jpeg_destroy_decompress(cinfo); | |||
| std::string err_msg = "Decode: image decompress failed."; | |||
| std::string err_msg = "Decode: image decode failed."; | |||
| RETURN_STATUS_UNEXPECTED(err_msg); | |||
| } | |||
| } | |||
| @@ -390,7 +400,7 @@ Status HwcToChw(std::shared_ptr<Tensor> input, std::shared_ptr<Tensor> *output) | |||
| try { | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(input); | |||
| if (!input_cv->mat().data) { | |||
| RETURN_STATUS_UNEXPECTED("HwcToChw: load image failed."); | |||
| RETURN_STATUS_UNEXPECTED("HWC2CHW: load image failed."); | |||
| } | |||
| if (input_cv->Rank() == 2) { | |||
| // If input tensor is 2D, we assume we have hw dimensions | |||
| @@ -400,7 +410,7 @@ Status HwcToChw(std::shared_ptr<Tensor> input, std::shared_ptr<Tensor> *output) | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->shape().Size() < 2 || input_cv->shape().Size() > 3 || | |||
| (input_cv->shape().Size() == 3 && num_channels != 3 && num_channels != 1)) { | |||
| RETURN_STATUS_UNEXPECTED("HwcToChw: invalid image shape: number of channels does not equal 3 nor 1"); | |||
| RETURN_STATUS_UNEXPECTED("HWC2CHW: image shape is not <H,W,C>."); | |||
| } | |||
| cv::Mat output_img; | |||
| @@ -417,19 +427,19 @@ Status HwcToChw(std::shared_ptr<Tensor> input, std::shared_ptr<Tensor> *output) | |||
| *output = std::move(output_cv); | |||
| return Status::OK(); | |||
| } catch (const cv::Exception &e) { | |||
| RETURN_STATUS_UNEXPECTED("HwcToChw: " + std::string(e.what())); | |||
| RETURN_STATUS_UNEXPECTED("HWC2CHW: " + std::string(e.what())); | |||
| } | |||
| } | |||
| Status MaskWithTensor(const std::shared_ptr<Tensor> &sub_mat, std::shared_ptr<Tensor> *input, int x, int y, | |||
| int crop_width, int crop_height, ImageFormat image_format) { | |||
| if (image_format == ImageFormat::HWC) { | |||
| if ((*input)->Rank() != 3 || ((*input)->shape()[2] != 1 && (*input)->shape()[2] != 3)) { | |||
| if (CheckTensorShape(*input, 2)) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "CutMixBatch: MaskWithTensor failed: " | |||
| "input shape doesn't match <H,W,C> format."); | |||
| } | |||
| if (sub_mat->Rank() != 3 || (sub_mat->shape()[2] != 1 && sub_mat->shape()[2] != 3)) { | |||
| if (CheckTensorShape(sub_mat, 2)) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "CutMixBatch: MaskWithTensor failed: " | |||
| "sub_mat shape doesn't match <H,W,C> format."); | |||
| @@ -443,12 +453,12 @@ Status MaskWithTensor(const std::shared_ptr<Tensor> &sub_mat, std::shared_ptr<Te | |||
| } | |||
| } | |||
| } else if (image_format == ImageFormat::CHW) { | |||
| if ((*input)->Rank() != 3 || ((*input)->shape()[0] != 1 && (*input)->shape()[0] != 3)) { | |||
| if (CheckTensorShape(*input, 0)) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "CutMixBatch: MaskWithTensor failed: " | |||
| "input shape doesn't match <C,H,W> format."); | |||
| } | |||
| if (sub_mat->Rank() != 3 || (sub_mat->shape()[0] != 1 && sub_mat->shape()[0] != 3)) { | |||
| if (CheckTensorShape(sub_mat, 0)) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "CutMixBatch: MaskWithTensor failed: " | |||
| "sub_mat shape doesn't match <C,H,W> format."); | |||
| @@ -512,9 +522,7 @@ Status SwapRedAndBlue(std::shared_ptr<Tensor> input, std::shared_ptr<Tensor> *ou | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(std::move(input)); | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->shape().Size() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "SwapRedBlue: invalid input shape, " | |||
| "number of channels does not equal 3"); | |||
| RETURN_STATUS_UNEXPECTED("SwapRedBlue: image shape is not <H,W,C>."); | |||
| } | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| @@ -616,7 +624,7 @@ Status Normalize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> * | |||
| RETURN_STATUS_UNEXPECTED("Normalize: load image failed."); | |||
| } | |||
| if (input_cv->Rank() != 3) { | |||
| RETURN_STATUS_UNEXPECTED("Normalize: only support 3 channels image."); | |||
| RETURN_STATUS_UNEXPECTED("Normalize: image shape is not <H,W,C>."); | |||
| } | |||
| cv::Mat in_image = input_cv->mat(); | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| @@ -713,9 +721,7 @@ Status AdjustBrightness(const std::shared_ptr<Tensor> &input, std::shared_ptr<Te | |||
| } | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->Rank() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "AdjustBrightness: image shape is incorrect: " | |||
| "number of channels does not equal 3"); | |||
| RETURN_STATUS_UNEXPECTED("AdjustBrightness: image shape is not <H,W,C>."); | |||
| } | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| @@ -732,13 +738,11 @@ Status AdjustContrast(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tens | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(input); | |||
| cv::Mat input_img = input_cv->mat(); | |||
| if (!input_cv->mat().data) { | |||
| RETURN_STATUS_UNEXPECTED("AdjustContrast: "); | |||
| RETURN_STATUS_UNEXPECTED("AdjustContrast: load image failed."); | |||
| } | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->Rank() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "AdjustContrast: image shape is incorrect: " | |||
| "number of channels does not equal 3"); | |||
| RETURN_STATUS_UNEXPECTED("AdjustContrast: image shape is not <H,W,C>."); | |||
| } | |||
| cv::Mat gray, output_img; | |||
| cv::cvtColor(input_img, gray, CV_RGB2GRAY); | |||
| @@ -773,7 +777,7 @@ Status AutoContrast(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor | |||
| // Get number of channels and image matrix | |||
| std::size_t num_of_channels = input_cv->shape()[2]; | |||
| if (num_of_channels != 1 && num_of_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED("AutoContrast: the number of channels is not 1 or 3."); | |||
| RETURN_STATUS_UNEXPECTED("AutoContrast: image shape is not <H,W,C>."); | |||
| } | |||
| cv::Mat image = input_cv->mat(); | |||
| // Separate the image to channels | |||
| @@ -843,9 +847,7 @@ Status AdjustSaturation(const std::shared_ptr<Tensor> &input, std::shared_ptr<Te | |||
| } | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->Rank() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED( | |||
| "AdjustSaturation: image shape is incorrect: " | |||
| "number of channels does not equal 3"); | |||
| RETURN_STATUS_UNEXPECTED("AdjustSaturation: image shape is not <H,W,C>."); | |||
| } | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| @@ -873,7 +875,7 @@ Status AdjustHue(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> * | |||
| } | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->Rank() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED("AdjustHue: number of channels does not equal 3"); | |||
| RETURN_STATUS_UNEXPECTED("AdjustHue: image shape is not <H,W,C>."); | |||
| } | |||
| std::shared_ptr<CVTensor> output_cv; | |||
| RETURN_IF_NOT_OK(CVTensor::CreateEmpty(input_cv->shape(), input_cv->type(), &output_cv)); | |||
| @@ -912,7 +914,7 @@ Status Equalize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *o | |||
| // Get number of channels and image matrix | |||
| std::size_t num_of_channels = input_cv->shape()[2]; | |||
| if (num_of_channels != 1 && num_of_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED("Equalize: number of channels is not 1 or 3."); | |||
| RETURN_STATUS_UNEXPECTED("Equalize: image shape is not <H,W,C>."); | |||
| } | |||
| cv::Mat image = input_cv->mat(); | |||
| // Separate the image to channels | |||
| @@ -944,17 +946,17 @@ Status Erase(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *outp | |||
| std::shared_ptr<CVTensor> input_cv = CVTensor::AsCVTensor(input); | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->mat().data == nullptr) { | |||
| RETURN_STATUS_UNEXPECTED("Erase: load image failed."); | |||
| RETURN_STATUS_UNEXPECTED("CutOut: load image failed."); | |||
| } | |||
| if (input_cv->Rank() != 3 || num_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED("Erase: number of channels is not 1 or 3."); | |||
| RETURN_STATUS_UNEXPECTED("CutOut: image shape is not <H,W,C> or <H,W>."); | |||
| } | |||
| cv::Mat input_img = input_cv->mat(); | |||
| int32_t image_h = input_cv->shape()[0]; | |||
| int32_t image_w = input_cv->shape()[1]; | |||
| // check if erase size is bigger than image itself | |||
| if (box_height > image_h || box_width > image_w) { | |||
| RETURN_STATUS_UNEXPECTED("Erase: box size is too large for image erase"); | |||
| RETURN_STATUS_UNEXPECTED("CutOut: box size is too large for image erase"); | |||
| } | |||
| // for random color | |||
| @@ -997,7 +999,7 @@ Status Erase(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *outp | |||
| *output = std::static_pointer_cast<Tensor>(input); | |||
| return Status::OK(); | |||
| } catch (const cv::Exception &e) { | |||
| RETURN_STATUS_UNEXPECTED("Erase: " + std::string(e.what())); | |||
| RETURN_STATUS_UNEXPECTED("CutOut: " + std::string(e.what())); | |||
| } | |||
| } | |||
| @@ -1035,8 +1037,8 @@ Status RgbaToRgb(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> * | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->shape().Size() != 3 || num_channels != 4) { | |||
| std::string err_msg = | |||
| "RgbaToRgb: Number of channels does not equal 4, " | |||
| "got : " + | |||
| "RgbaToRgb: Number of channels of image does not equal 4, " | |||
| "but got : " + | |||
| std::to_string(num_channels); | |||
| RETURN_STATUS_UNEXPECTED(err_msg); | |||
| } | |||
| @@ -1057,8 +1059,8 @@ Status RgbaToBgr(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> * | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (input_cv->shape().Size() != 3 || num_channels != 4) { | |||
| std::string err_msg = | |||
| "RgbaToBgr: number of channels does not equal 4, " | |||
| "got : " + | |||
| "RgbaToBgr: number of channels of image should be 4, " | |||
| "but got : " + | |||
| std::to_string(num_channels); | |||
| RETURN_STATUS_UNEXPECTED(err_msg); | |||
| } | |||
| @@ -56,6 +56,12 @@ int GetCVInterpolationMode(InterpolationMode mode); | |||
| /// \return Status code | |||
| int GetCVBorderType(BorderType type); | |||
| /// \brief Returns the check result of tensor rank and tensor shape | |||
| /// \param[in] tensor: The input tensor need to check | |||
| /// \param[in] channel: The channel index of tensor shape. | |||
| /// \param[out] return true if channel of tensor shape is 1 or 3. | |||
| bool CheckTensorShape(const std::shared_ptr<Tensor> &tensor, const int &channel); | |||
| /// \brief Returns flipped image | |||
| /// \param[in] input/output: Tensor of shape <H,W,C> or <H,W> and any OpenCv compatible type, see CVTensor. | |||
| /// \param flip_code: 1 for Horizontal (around y-axis), 0 for Vertical (around x-axis), -1 for both | |||
| @@ -26,7 +26,7 @@ RandomColorOp::RandomColorOp(float t_lb, float t_ub) : rnd_(GetSeed()), dist_(t_ | |||
| Status RandomColorOp::Compute(const std::shared_ptr<Tensor> &in, std::shared_ptr<Tensor> *out) { | |||
| IO_CHECK(in, out); | |||
| if (in->Rank() != 3) { | |||
| RETURN_STATUS_UNEXPECTED("RandomColor: image must have 3 channels"); | |||
| RETURN_STATUS_UNEXPECTED("RandomColor: image shape is not <H,W,C>."); | |||
| } | |||
| // 0.5 pixel precision assuming an 8 bit image | |||
| const auto eps = 0.00195; | |||
| @@ -60,7 +60,7 @@ Status RandomCropOp::ImagePadding(const std::shared_ptr<Tensor> &input, std::sha | |||
| CHECK_FAIL_RETURN_UNEXPECTED(pad_top_ < input->shape()[0] * 3 && pad_bottom_ < input->shape()[0] * 3 && | |||
| pad_left_ < input->shape()[1] * 3 && pad_right_ < input->shape()[1] * 3, | |||
| "RandomCrop: padding size is too big, it's more than 3 times the original size."); | |||
| "Pad: padding size is three times bigger than the image size."); | |||
| RETURN_IF_NOT_OK( | |||
| Pad(input, pad_image, pad_top_, pad_bottom_, pad_left_, pad_right_, border_type_, fill_r_, fill_g_, fill_b_)); | |||
| @@ -93,9 +93,13 @@ Status RandomCropOp::ImagePadding(const std::shared_ptr<Tensor> &input, std::sha | |||
| *padded_image_w = (*pad_image)->shape()[1]; | |||
| } | |||
| if (crop_height_ == 0 || crop_width_ == 0) { | |||
| return Status(StatusCode::kShapeMisMatch, __LINE__, __FILE__, | |||
| "RandomCrop: invalid crop size, crop dimension is not allowed to be zero."); | |||
| } | |||
| if (*padded_image_h < crop_height_ || *padded_image_w < crop_width_ || crop_height_ == 0 || crop_width_ == 0) { | |||
| return Status(StatusCode::kShapeMisMatch, __LINE__, __FILE__, | |||
| "RandomCrop: crop size is greater than the image dimensions or is zero."); | |||
| "RandomCrop: invalid crop size, crop size is bigger than the image dimensions."); | |||
| } | |||
| return Status::OK(); | |||
| } | |||
| @@ -109,6 +113,10 @@ void RandomCropOp::GenRandomXY(int *x, int *y, const int32_t &padded_image_w, co | |||
| Status RandomCropOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) { | |||
| IO_CHECK(input, output); | |||
| if (input->Rank() != 3 && input->Rank() != 2) { | |||
| RETURN_STATUS_UNEXPECTED("RandomCrop: image shape is not <H,W,C> or <H,W>."); | |||
| } | |||
| // Apply padding first then crop | |||
| std::shared_ptr<Tensor> pad_image; | |||
| int32_t t_pad_top, t_pad_bottom, t_pad_left, t_pad_right; | |||
| @@ -29,9 +29,7 @@ const InterpolationMode ResizeOp::kDefInterpolation = InterpolationMode::kLinear | |||
| Status ResizeOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) { | |||
| IO_CHECK(input, output); | |||
| CHECK_FAIL_RETURN_UNEXPECTED( | |||
| input->shape().Size() >= 2, | |||
| "Resize: image shape " + std::to_string(input->shape().Size()) + " is not <H,W,C> or <H,W>."); | |||
| CHECK_FAIL_RETURN_UNEXPECTED(input->shape().Size() >= 2, "Resize: image shape is not <H,W,C> or <H,W>."); | |||
| int32_t output_h, output_w = 0; | |||
| int32_t input_h = static_cast<int>(input->shape()[0]); | |||
| int32_t input_w = static_cast<int>(input->shape()[1]); | |||
| @@ -41,7 +41,7 @@ Status SharpnessOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_pt | |||
| /// Get number of channels and image matrix | |||
| std::size_t num_of_channels = input_cv->shape()[2]; | |||
| if (num_of_channels != 1 && num_of_channels != 3) { | |||
| RETURN_STATUS_UNEXPECTED("Sharpness: number of channels is not 1 or 3."); | |||
| RETURN_STATUS_UNEXPECTED("Sharpness: image shape is not <H,W,C>."); | |||
| } | |||
| /// creating a smoothing filter. 1, 1, 1, | |||
| @@ -40,12 +40,12 @@ Status SolarizeOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr | |||
| } | |||
| if (input_cv->Rank() != 2 && input_cv->Rank() != 3) { | |||
| RETURN_STATUS_UNEXPECTED("Solarize: image shape is not of either <H,W,C> or <H,W>."); | |||
| RETURN_STATUS_UNEXPECTED("Solarize: image shape is not <H,W,C> or <H,W>."); | |||
| } | |||
| if (input_cv->Rank() == 3) { | |||
| int num_channels = input_cv->shape()[2]; | |||
| if (num_channels != 3 && num_channels != 1) { | |||
| RETURN_STATUS_UNEXPECTED("Solarize: number of channels is not 1 or 3."); | |||
| RETURN_STATUS_UNEXPECTED("Solarize: image shape is not <H,W,C>."); | |||
| } | |||
| } | |||
| @@ -89,11 +89,12 @@ ComputeReturn: | |||
| return ret; | |||
| ShapeMisMatch: | |||
| ret = Status(StatusCode::kShapeMisMatch, "PyFunc should return a numpy array or a numpy array tuple"); | |||
| ret = | |||
| Status(StatusCode::kShapeMisMatch, __LINE__, __FILE__, "PyFunc should return a numpy array or a numpy array tuple"); | |||
| goto ComputeReturn; | |||
| TimeoutError: | |||
| ret = Status(StatusCode::kTimeOut, "PyFunc execute time out"); | |||
| ret = Status(StatusCode::kTimeOut, __LINE__, __FILE__, "PyFunc execute time out"); | |||
| goto ComputeReturn; | |||
| } | |||
| @@ -60,7 +60,7 @@ constexpr char kCutOutOp[] = "CutOutOp"; | |||
| constexpr char kCropOp[] = "CropOp"; | |||
| constexpr char kDvppDecodeResizeCropJpegOp[] = "DvppDecodeResizeCropJpegOp"; | |||
| constexpr char kEqualizeOp[] = "EqualizeOp"; | |||
| constexpr char kHwcToChwOp[] = "HwcToChwOp"; | |||
| constexpr char kHwcToChwOp[] = "HWC2CHWOp"; | |||
| constexpr char kInvertOp[] = "InvertOp"; | |||
| constexpr char kMixUpBatchOp[] = "MixUpBatchOp"; | |||
| constexpr char kNormalizeOp[] = "NormalizeOp"; | |||
| @@ -44,7 +44,7 @@ std::string CodeAsString(const StatusCode c) { | |||
| s = "Interrupted system call"; | |||
| break; | |||
| case StatusCode::kShapeMisMatch: | |||
| s = "Shape is incorrect."; | |||
| s = "Shape is incorrect"; | |||
| break; | |||
| case StatusCode::kNoSpace: | |||
| s = "No space left on device"; | |||
| @@ -274,7 +274,7 @@ def test_coco_case_exception(): | |||
| pass | |||
| assert False | |||
| except RuntimeError as e: | |||
| assert "json.exception.parse_error" in str(e) | |||
| assert "failed to open json file" in str(e) | |||
| try: | |||
| sampler = ds.PKSampler(3) | |||
| @@ -58,7 +58,7 @@ def util_test_random_color_adjust_error(brightness=(1, 1), contrast=(1, 1), satu | |||
| c_image = item1["image"] | |||
| dataset_shape_1.append(c_image.shape) | |||
| error_msg = "number of channels does not equal 3" | |||
| error_msg = "image shape is not <H,W,C>" | |||
| assert error_msg in str(info.value) | |||
| @@ -261,7 +261,7 @@ def test_random_crop_04_c(): | |||
| data.create_dict_iterator(num_epochs=1).__next__() | |||
| except RuntimeError as e: | |||
| logger.info("Got an exception in DE: {}".format(str(e))) | |||
| assert "crop size is greater than the image dimensions or is zero" in str(e) | |||
| assert "crop size is bigger than the image dimensions" in str(e) | |||
| def test_random_crop_04_py(): | |||
| """ | |||
| @@ -273,7 +273,7 @@ def test_random_crop_with_bbox_op_bad_padding(): | |||
| break | |||
| except RuntimeError as err: | |||
| logger.info("Got an exception in DE: {}".format(str(err))) | |||
| assert "padding size is too big, it\'s more than 3 times the original size." in str(err) | |||
| assert "padding size is three times bigger than the image size" in str(err) | |||
| if __name__ == "__main__": | |||