forked from mindspore-Ecosystem/mindspore
fix canny when size is 7
This commit is contained in:
parent
0451a800bc
commit
b88a68c9e8
|
@ -32,7 +32,7 @@
|
|||
namespace mindspore {
|
||||
namespace dataset {
|
||||
|
||||
static void GetSobelKernel(float *kernel, int flag, int ksize) {
|
||||
static void GetSobelKernel(float *kernel, int flag, int ksize, double scale) {
|
||||
std::vector<float> buffer(ksize + 1);
|
||||
float *ptr = kernel;
|
||||
|
||||
|
@ -70,12 +70,14 @@ static void GetSobelKernel(float *kernel, int flag, int ksize) {
|
|||
}
|
||||
}
|
||||
|
||||
scale = flag == 0 ? scale : 1.0;
|
||||
for (int i = 0; i < ksize; i++) {
|
||||
ptr[i] = buffer[i];
|
||||
ptr[i] = buffer[i] * scale;
|
||||
}
|
||||
}
|
||||
|
||||
bool Sobel(const LiteMat &src, LiteMat &dst, int flag_x, int flag_y, int ksize, PaddBorderType pad_type) { // NOLINT
|
||||
bool Sobel(const LiteMat &src, LiteMat &dst, int flag_x, int flag_y, int ksize, double scale, // NOLINT
|
||||
PaddBorderType pad_type) {
|
||||
if (src.IsEmpty() || src.data_type_ != LDataType::UINT8) {
|
||||
return false;
|
||||
}
|
||||
|
@ -92,8 +94,8 @@ bool Sobel(const LiteMat &src, LiteMat &dst, int flag_x, int flag_y, int ksize,
|
|||
kx.Init(ksize, 1, 1, LDataType::FLOAT32);
|
||||
ky.Init(1, ksize, 1, LDataType::FLOAT32);
|
||||
|
||||
GetSobelKernel(kx, flag_x, ksize);
|
||||
GetSobelKernel(ky, flag_y, ksize);
|
||||
GetSobelKernel(kx, flag_x, ksize, scale);
|
||||
GetSobelKernel(ky, flag_y, ksize, scale);
|
||||
|
||||
return ConvRowCol(src, kx, ky, dst, LDataType::FLOAT32, pad_type);
|
||||
}
|
||||
|
@ -106,6 +108,24 @@ static float GetEdge(const std::vector<float> &temp, int width, int height, int
|
|||
}
|
||||
}
|
||||
|
||||
static float Round(float value) {
|
||||
// rounding if the result is even
|
||||
// eg. 1.5 -> 2, 2.5 -> 2
|
||||
float rnd = round(value);
|
||||
float rnd_l = floor(value);
|
||||
float rnd_h = ceil(value);
|
||||
if (value - rnd_l == 0.5) {
|
||||
if (fmod(rnd, 2) == 0) {
|
||||
return rnd;
|
||||
} else if (value > 0) {
|
||||
return rnd_l;
|
||||
} else {
|
||||
return rnd_h;
|
||||
}
|
||||
}
|
||||
return rnd;
|
||||
}
|
||||
|
||||
static void NonMaximumSuppression(const LiteMat &gx, const LiteMat &gy, LiteMat &edges, bool L2gradient) { // NOLINT
|
||||
edges.Init(gx.width_, gx.height_, gx.channel_, gx.data_type_);
|
||||
|
||||
|
@ -116,8 +136,8 @@ static void NonMaximumSuppression(const LiteMat &gx, const LiteMat &gy, LiteMat
|
|||
int size = gx.height_ * gx.width_;
|
||||
std::vector<float> temp(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
float gx_value = gx_ptr[i];
|
||||
float gy_value = gy_ptr[i];
|
||||
float gx_value = Round(gx_ptr[i]);
|
||||
float gy_value = Round(gy_ptr[i]);
|
||||
if (L2gradient) {
|
||||
temp[i] = sqrt(gx_value * gx_value + gy_value * gy_value);
|
||||
} else {
|
||||
|
@ -127,8 +147,8 @@ static void NonMaximumSuppression(const LiteMat &gx, const LiteMat &gy, LiteMat
|
|||
|
||||
for (int y = 0; y < gx.height_; y++) {
|
||||
for (int x = 0; x < gx.width_; x++) {
|
||||
float gx_value = gx_ptr[y * gx.width_ + x];
|
||||
float gy_value = gy_ptr[y * gx.width_ + x];
|
||||
float gx_value = Round(gx_ptr[y * gx.width_ + x]);
|
||||
float gy_value = Round(gy_ptr[y * gx.width_ + x]);
|
||||
|
||||
float gx_value_abs = std::abs(gx_value);
|
||||
float gy_value_abs = std::abs(gy_value);
|
||||
|
@ -242,9 +262,13 @@ bool Canny(const LiteMat &src, LiteMat &dst, double low_thresh, double high_thre
|
|||
dst.Init(src.width_, src.height_, src.channel_, src.data_type_);
|
||||
}
|
||||
|
||||
double scale = ksize == 7 ? 1 / 16.0 : 1.0;
|
||||
low_thresh *= scale;
|
||||
high_thresh *= scale;
|
||||
|
||||
LiteMat gx, gy;
|
||||
Sobel(src, gx, 1, 0, ksize, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(src, gy, 0, 1, ksize, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(src, gx, 1, 0, ksize, scale, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(src, gy, 0, 1, ksize, scale, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
|
||||
LiteMat edges;
|
||||
NonMaximumSuppression(gx, gy, edges, L2gradient);
|
||||
|
|
|
@ -148,7 +148,8 @@ bool ConvRowCol(const LiteMat &src, const LiteMat &kx, const LiteMat &ky, LiteMa
|
|||
PaddBorderType pad_type = PaddBorderType::PADD_BORDER_DEFAULT);
|
||||
|
||||
/// \brief Filter the image by a Sobel kernel
|
||||
bool Sobel(const LiteMat &src, LiteMat &dst, int flag_x, int flag_y, int ksize, PaddBorderType pad_type);
|
||||
bool Sobel(const LiteMat &src, LiteMat &dst, int flag_x, int flag_y, int ksize = 3, double scale = 1.0,
|
||||
PaddBorderType pad_type = PaddBorderType::PADD_BORDER_DEFAULT);
|
||||
|
||||
/// \brief Convert RGB image or color image to grayscale image
|
||||
bool ConvertRgbToGray(const LiteMat &src, LDataType data_type, int w, int h, LiteMat &mat);
|
||||
|
|
|
@ -1595,6 +1595,35 @@ TEST_F(MindDataImageProcess, TestCannySize5) {
|
|||
EXPECT_EQ(distance, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestCannySize7) {
|
||||
std::string filename = "data/dataset/apple.jpg";
|
||||
cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR);
|
||||
cv::Mat gray_image;
|
||||
cv::cvtColor(src_image, gray_image, CV_BGR2GRAY);
|
||||
cv::Mat dst_image;
|
||||
cv::Canny(gray_image, dst_image, 110, 220, 7);
|
||||
|
||||
cv::Mat rgba_mat;
|
||||
cv::cvtColor(src_image, rgba_mat, CV_BGR2RGBA);
|
||||
bool ret = false;
|
||||
LiteMat lite_mat_gray;
|
||||
ret =
|
||||
InitFromPixel(rgba_mat.data, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_gray);
|
||||
ASSERT_TRUE(ret == true);
|
||||
|
||||
LiteMat lite_mat_dst;
|
||||
ret = Canny(lite_mat_gray, lite_mat_dst, 110, 220, 7);
|
||||
ASSERT_TRUE(ret == true);
|
||||
|
||||
int total_size = lite_mat_dst.height_ * lite_mat_dst.width_ * lite_mat_dst.channel_;
|
||||
double distance = 0.0f;
|
||||
for (int i = 0; i < total_size; i++) {
|
||||
distance += pow((uint8_t)dst_image.data[i] - ((uint8_t *)lite_mat_dst)[i], 2);
|
||||
}
|
||||
distance = sqrt(distance / total_size);
|
||||
EXPECT_EQ(distance, 0.0f);
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestCannyL2) {
|
||||
std::string filename = "data/dataset/apple.jpg";
|
||||
cv::Mat src_image = cv::imread(filename, cv::ImreadModes::IMREAD_COLOR);
|
||||
|
@ -1689,8 +1718,8 @@ TEST_F(MindDataImageProcess, TestSobel) {
|
|||
ASSERT_TRUE(ret == true);
|
||||
LiteMat lite_mat_x;
|
||||
LiteMat lite_mat_y;
|
||||
Sobel(lite_mat_gray, lite_mat_x, 1, 0, 3, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(lite_mat_gray, lite_mat_y, 0, 1, 3, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(lite_mat_gray, lite_mat_x, 1, 0, 3, 1, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(lite_mat_gray, lite_mat_y, 0, 1, 3, 1, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
ASSERT_TRUE(ret == true);
|
||||
|
||||
cv::Mat dst_imageX(lite_mat_x.height_, lite_mat_x.width_, CV_32FC1, lite_mat_x.data_ptr_);
|
||||
|
@ -1731,7 +1760,7 @@ TEST_F(MindDataImageProcess, TestSobelFlag) {
|
|||
InitFromPixel(rgba_mat.data, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_gray);
|
||||
ASSERT_TRUE(ret == true);
|
||||
LiteMat lite_mat_x;
|
||||
Sobel(lite_mat_gray, lite_mat_x, 3, 1, 5, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
Sobel(lite_mat_gray, lite_mat_x, 3, 1, 5, 1, PaddBorderType::PADD_BORDER_REPLICATE);
|
||||
ASSERT_TRUE(ret == true);
|
||||
|
||||
cv::Mat dst_imageX(lite_mat_x.height_, lite_mat_x.width_, CV_32FC1, lite_mat_x.data_ptr_);
|
||||
|
|
Loading…
Reference in New Issue