OpenCV中生成的图案图像不正确

时间:2017-09-01 15:33:50

标签: c++ opencv image-processing

内容:OpenCV C ++中的图像处理。

要求是在外部 Mat 图像上创建大小为256 X 256的 Mat 图案的图块。用户指定外部 Mat 图像的宽度和高度。

要做到这一点,我创建了以下OpenCV C ++函数:

Y

如果你能看到上面的else语句,我试着反过来第一个条件,并使值绝对。

我得到的输出如下所示:enter image description here

预期输出是对角线第一部分的倒数。朝向对角线的颜色越深越浅。

我尝试用许多语句替换 var player: AVAudioPlayer? func slowPlay() { do { let ap = Bundle.main.path(forResource: "slowslow", ofType: "mp3") self.player = try AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: ap!) as URL) } catch { //// } let session = AVAudioSession.sharedInstance() do { try session.setCategory(AVAudioSessionCategoryPlayback) } catch { //catch error here } self.player?.play() } func slowStop() { self.player?.stop() } 。我是输出结构。 更改应仅在else语句中进行。我的其余代码是正确的,因为我的输出的一半(顶部对角线)是正确的。

感谢您的任何帮助以解决此问题。相信我,计算所有图形[X-Y轴]和数学计算[像素访问]来获得所需的输出是非常有趣的。

1 个答案:

答案 0 :(得分:2)

我首先将问题分为两部分:

  • 生成包含正确模式的单个图块
  • 使用该图块(或算法)生成整个图像

生成平铺

目标是生成包含渐变的256x256灰度图像:

  • 左上角全是黑色
  • 右下角全是黑色
  • 从左下角到右上角的对角线都是白色

你得到了对角线以上的部分,但无论如何我们都要检查它。

左上角的坐标是(0,0),我们期望强度为0. - > row + col == 0

对角线一端的坐标是(255,0),我们期望强度为255. - > row + col == 255

对角线的另一端是(0,255) - > row + col == 255

让我们尝试对角线上的另一个点,(254,1) - >再次row + col == 255

好的,现在是对角线上方的一点,(254,0) - > row + col == 254 - 稍微不那么白,正如我们所期望的那样。

接下来,让我们尝试在对角线下方的一个点,比如说(255,1) - > row + col == 256。如果我们将它转​​换为8位整数,我们得到0,但我们期望254,就像前一种情况一样。

最后,右下角(255,255) - > row + col == 510。如果我们将它转​​换为8位整数,我们得到254,但我们期望0。

让我们尝试一下:

  • 256 + 254 == 510
  • 510 + 0 == 510

我们看到一个算法: *如果row + col的总和小于256,则使用总和 *否则从510中减去总和并使用结果

示例代码:

cv::Mat make_tile()
{
    int32_t const TILE_SIZE(256);
    cv::Mat image(TILE_SIZE, TILE_SIZE, CV_8UC1);
    for (int32_t r(0); r < TILE_SIZE; ++r) {
        for (int32_t c(0); c < TILE_SIZE; ++c) {
            int32_t sum(r + c);
            if (sum < TILE_SIZE) {
                image.at<uint8_t>(r, c) = static_cast<uint8_t>(sum);
            } else {
                image.at<uint8_t>(r, c) = static_cast<uint8_t>(2 * (TILE_SIZE - 1) - sum);
            }            
        }
    }
    return image;
}

单个瓷砖:

Single tile

生成瓷砖图像

现在我们有了一个完整的图块,我们可以通过迭代目标图像的图块大小的ROI并复制相同大小的图块ROI来生成完整图像。

示例代码:

#include <opencv2/opencv.hpp>
#include <cstdint>

cv::Mat make_tile()
{
    int32_t const TILE_SIZE(256);
    cv::Mat image(TILE_SIZE, TILE_SIZE, CV_8UC1);
    for (int32_t r(0); r < TILE_SIZE; ++r) {
        for (int32_t c(0); c < TILE_SIZE; ++c) {
            int32_t sum(r + c);
            if (sum < TILE_SIZE) {
                image.at<uint8_t>(r, c) = static_cast<uint8_t>(sum);
            } else {
                image.at<uint8_t>(r, c) = static_cast<uint8_t>(2 * (TILE_SIZE - 1) - sum);
            }            
        }
    }
    return image;
}

int main()
{   
    cv::Mat tile(make_tile());

    cv::Mat result(600, 800, CV_8UC1);

    for (int32_t r(0); r < result.rows; r += tile.rows) {
        for (int32_t c(0); c < result.cols; c += tile.cols) {
            // Handle incomplete tiles
            int32_t end_r(std::min(r + tile.rows, result.rows));
            int32_t end_c(std::min(c + tile.cols, result.cols));
            // Get current target tile ROI and source ROI of same size
            cv::Mat target_roi(result(cv::Range(r, end_r), cv::Range(c, end_c)));
            cv::Mat source_roi(tile(cv::Range(0, target_roi.rows), cv::Range(0, target_roi.cols)));
            // Copy the tile
            source_roi.copyTo(target_roi);
        }
    }

    cv::imwrite("gradient.png", tile);
    cv::imwrite("gradient_big.png", result);
}

完整图片:

Complete image