2017-08-07 17 views
0

我想模糊的图像模糊的图像。在这一点上,我可以模糊它没有边界。我读过我可以通过将数据容器放入更大的数据容器来实现我的目标。我试过了,但是我不能成功地做到这一点。也许有人知道更简单的解决方案来做到这一点这里是我的代码:用纯C++

Image Blur::transform(const Image &inputImage) 
{ 
    Image input = (inputImage.type != ImageType::Grayscale) 
      ? Grayscale().transform(inputImage) 
      : inputImage; 

    std::cout << "Blurring" << std::endl; 

    Image output = input; 

    auto indexAt = [&input](int row, int col) { return row * input.size.m_width + col; }; 

    for (int row = m_BLUR_MASK_RADIUS; row < output.size.m_height - m_BLUR_MASK_RADIUS; row++) 
    { 
     for (int col = m_BLUR_MASK_RADIUS; col < output.size.m_width - m_BLUR_MASK_RADIUS; col++) 
     { 
      std::vector<uint8_t> pixel_values; 
      for (int row_offset = -m_BLUR_MASK_RADIUS; row_offset <= m_BLUR_MASK_RADIUS; row_offset++) 
      { 
       for (int col_offset = -m_BLUR_MASK_RADIUS; col_offset <= m_BLUR_MASK_RADIUS; col_offset++) 
       { 
        const int offset_pixel_index = indexAt(row + row_offset, col + col_offset); 
        pixel_values.push_back(input.data[offset_pixel_index]); 
       } 
      } 

      const int center_pixel_index = indexAt(row, col); 
      output.data[center_pixel_index] = getModifiedValue(pixel_values); 
     } 
    } 

    return output; 
} 

哪里Image是如下:

struct Image 
{ 
    std::vector<uint8_t> data; 
    Size size; 
    ImageType type; 

    int pixelCount() const { 
     return size.m_height * size.m_width; 
    } 

    Image() {} 
    Image(Size _size, ImageType _type) : size(_size), type(_type) {} 
    ~Image() {} 
}; 

struct Size 
{ 
    int m_width; 
    int m_height; 

    Size() {} 
    Size(int width, int height) : m_width(width), m_height(height) {} 
}; 

enum class ImageType 
{ 
    Rgba, 
    Grayscale 
}; 

所以你能帮忙吗?

+1

如果你尝试过,你应该张贴,你写了没有工作的代码。否则,唯一提及并不意味着太多。而且你不需要一个更大的容器来模糊图像,边缘检查条件就可以做到。 –

+0

@BartekBanachewicz上周试了一下。不幸的是,没有该代码已经 – gawron103

回答

0

我不完全知道什么是你的问题,如果要对其进行模糊处理,与边框或无边界模糊,所以我会尽量回答关于这两种方法。

首先,如果模糊了边界上,你需要承担什么是落后的边界值。通常你会重用边界值。

x index -2 | -1 | 0 | 1 | 2 
     --------------------------- 
    color ? | ? | C1 | C2 | C3 

所以C1复制到-1,-2指数

x index -2 | -1 | 0 | 1 | 2 
     --------------------------- 
    color C1 | C1 | C1 | C2 | C3 

也就是说,

我可以把我的数据容器到更大的数据达到我的目标 容器

您可以通过创建新的图像更大的图像做,复制边境VAL你要走出去边境。如果模糊的它的内部部分(源indicies [0,N]),然后丢弃外的边界值(因为它们不是在原始图像相关)。

3x3的图像例如:

C1 | C2 | C3 
------------ 
C5 | C5 | C6 
------------ 
C7 | C8 | C9 

添加1模糊半径

C1 | C1 | C2 | C3 | C3 
---------------------- 
C1 | C1 | C2 | C3 | C3 
---------------------- 
C5 | C5 | C5 | C6 | C6 
---------------------- 
C7 | C7 | C8 | C9 | C9 
---------------------- 
C7 | C7 | C8 | C9 | C9 

现在您在指数上indicies [1,3]计算5倍图像的模糊用3×盒和它写成模糊图像与3x3。这就是你的功能几乎已经做的(除了调整大小)。

Image transformWithExtending(const Image &inputImage) 
{ 
    Image input = (inputImage.type != ImageType::Grayscale) 
     ? Grayscale().transform(inputImage) 
     : inputImage; 
    Image newInput = Image({ input.size.m_width + 2 * m_BLUR_MASK_RADIUS, input.size.m_height + 2 * m_BLUR_MASK_RADIUS }, input.type); 

    auto indexAt = [&input](int row, int col) { return row * input.size.m_width + col; }; 
    auto clamp = [&input](int x, int minv, int maxv) {return std::min(std::max(x, minv), maxv); } // std::clamp is only in C++17 
    // indexing in source image (with negatives) 
    for (int row = -m_BLUR_MASK_RADIUS; row < input.size.m_height + m_BLUR_MASK_RADIUS; row++) 
     for (int col = -m_BLUR_MASK_RADIUS; col < input.size.m_width + m_BLUR_MASK_RADIUS; col++) 
      newInput.data.push_back(input.data[indexAt(clamp(row, 0,input.size.m_width - 1), clamp(row, 0, input.size.m_height - 1))]); 


    // now transform it with previous function 
    Transform(newInput) 

    // and resize... 
    // TODO 
    // 
    return output; 
} 

但现在你可以问自己:为什么所有这些数据拷贝到临时图像,如果你能选择的边界像素,而不是一个-OF-得到相同的结果通过投入更大的容器

模糊填充过滤器值时边框?只需将边界以外的指示符夹紧即可。这给:

迷离,无需投入更大的容器:(只从你的函数几道变化)

Image Blur::transformWithBorders(const Image &inputImage) 
{ 
    Image input = (inputImage.type != ImageType::Grayscale) 
     ? Grayscale().transform(inputImage) 
     : inputImage; 

    std::cout << "Blurring" << std::endl; 

    Image output = input; 

    auto indexAt = [&input](int row, int col) { return row * input.size.m_width + col; }; 
    auto clamp = [&input](int x, int minv, int maxv) {return std::min(std::max(x, minv), maxv); } // std::clamp is only in C++17 

    for (int row = 0; row < output.size.m_height; row++) // go over whole image 
    { 
     for (int col = 0; col < output.size.m_width; col++) // go over whole image 
     { 
      std::vector<uint8_t> pixel_values; 
      for (int row_offset = -m_BLUR_MASK_RADIUS; row_offset <= m_BLUR_MASK_RADIUS; row_offset++) 
      { 
       for (int col_offset = -m_BLUR_MASK_RADIUS; col_offset <= m_BLUR_MASK_RADIUS; col_offset++) 
       { 
        // and clamp indicies here 
        const int offset_pixel_index = indexAt(clamp(row + row_offset, 0, output.size.m_height - 1), clamp(col + col_offset,0, output.size.m_width - 1)); 
        pixel_values.push_back(input.data[offset_pixel_index]); 
       } 
      } 

      const int center_pixel_index = indexAt(row, col); 
      output.data[center_pixel_index] = getModifiedValue(pixel_values); 
     } 
    } 

    return output; 
} 
+0

谢谢!好的解决方案 – gawron103