在C ++ OpenCV中为图像制作32x32部分?

时间:2018-03-08 22:33:42

标签: c++ opencv image-processing

我想拍摄灰度图像并将其划分为32x32个部分。每个部分将包含像素,并根据其强度和体积,它们将被视为1或0.

我的想法是,我会将这些部分命名为"(x,y)"。例如:

Section(1,1)包含这个强度范围内的许多像素,因此这是1。

这有意义吗?我试着寻找这个问题的答案,但是将图像分成重叠部分似乎并没有在OpenCV社区产生任何结果。请记住,我不想改变图像的外观,只需将其分成32x32表,其中(x,y)为"""图片。

1 个答案:

答案 0 :(得分:2)

是的,你可以这样做。这是代码。边缘粗糙,但它可以满足您的要求。请参阅代码中的注释以获得解释。

#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

struct BradleysImage
{
  int rows;
  int cols;

  cv::Mat data;

  int intensity_threshold;
  int count_threshold;

  cv::Mat buff = cv::Mat(32, 32, CV_8UC1);

  // When we call the operator with arguments y and x, we check
  // the region(y,x). We then count the number of pixels within
  // that region that are greater than some threshold. If the 
  // count is greater than desired number, we return 255, else 0.
  int operator()(int y, int x) const
  {
    int j = y*32;
    int i = x*32;

    auto window = cv::Rect(i, j, 32, 32);

    // threshold window contents
    cv::threshold(data(window), buff, intensity_threshold, 1, CV_THRESH_BINARY);

    int num_over_threshold = cv::countNonZero(buff);

    return num_over_threshold > count_threshold ? 255 : 0;
  }

};

int main() {

  // Input image
  cv::Mat img = cv::imread("walken.jpg", CV_8UC1);

  // I resize it so that I get dimensions divisible 
  // by 32 and get better looking result
  cv::Mat resized;
  cv::resize(img, resized, cv::Size(3200, 3200));

  BradleysImage b; // I had no idea how to name this so I used your nick
  b.rows = resized.rows / 32;
  b.cols = resized.cols / 32;
  b.data = resized;
  b.intensity_threshold = 128; // just some threshold
  b.count_threshold = 512; 

  cv::Mat result(b.rows -1, b.cols-1, CV_8UC1);
  for(int y = 0; y < result.rows; ++y)
    for(int x = 0; x < result.cols; ++x)
      result.at<uint8_t>(y, x) = b(y, x);


  imwrite("walken.png", result); 

  return 0;
}

我使用了Christopher Walken's image from Wikipedia并获得了这个结果:

walken