我想拍摄灰度图像并将其划分为32x32个部分。每个部分将包含像素,并根据其强度和体积,它们将被视为1或0.
我的想法是,我会将这些部分命名为"(x,y)"。例如:
Section(1,1)包含这个强度范围内的许多像素,因此这是1。
这有意义吗?我试着寻找这个问题的答案,但是将图像分成重叠部分似乎并没有在OpenCV社区产生任何结果。请记住,我不想改变图像的外观,只需将其分成32x32表,其中(x,y)为"""图片。
答案 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并获得了这个结果: