灰度图像上的LoG滤镜另存为二进制文件

时间:2019-01-06 19:16:10

标签: c++ image-processing graphics computer-vision

我正在尝试在具有静态蒙版5x5并在applyFilter()函数中进行卷积编码的图像上实现LoG过滤器。但是,无论使用哪种口罩,我都得到奇怪的结果。保存图像而不将其传递给功能正在起作用,因此问题就在这里,有人可以给我任何建议吗?

在执行脚本期间,将根据传递给CLI的尺寸从目录中读取图像,即./main 1500 1200将打开infile1500_1200.bin中的图像

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <chrono>

typedef std::vector<uint8_t> vec;
typedef std::vector<vec> matrix;
typedef std::vector<double> kernelRow;
typedef std::vector<kernelRow> kernel;

matrix toMatrix(const vec &flat_vec, std::size_t ncols)
{
    const auto nrows = flat_vec.size() / ncols;
    matrix mtx;
    const auto begin = std::begin(flat_vec);
    for (std::size_t row = 0; row < nrows; ++row) {
        mtx.push_back({ begin + row * ncols, begin + (row + 1)*ncols });
    }
    return mtx;
}

vec readFile(std::string fileName)
{
    std::ifstream inFile;
    vec rawFileBuffer;
    std::cout << "Reading image: " << fileName << std::endl;
    inFile.open(fileName, std::ios::in | std::ios::binary);
    inFile.seekg(0, std::ios::end);
    size_t filesize = inFile.tellg();
    inFile.seekg(0, std::ios::beg);
    rawFileBuffer.resize(filesize / sizeof(uint8_t));
    inFile.read((char *)rawFileBuffer.data(), filesize);
    inFile.close();
    return rawFileBuffer;
}

matrix getImageByFilename(std::string filename, int row)
{
    vec fileContent = readFile(filename);
    matrix image = toMatrix(fileContent, row);
    return image;
}

void saveImage(std::string fileName, matrix image)
{
    std::ofstream output(fileName, std::ios::out | std::ios::binary);
    for (const auto &row : image)
    {
        for (const auto &col : row)
        {
            output << col;
        }
    }
    output.close();
    std::cout << "File: " << fileName << "is saved." << std::endl;
}


kernel getLogKernel()
{
    kernel kernel{
        {0,0,1,0,0},
        {0,1,2,1,0},
        {1,2,-16,2,1},
        {0,1,2,1,0},
        {0,0,1,0,0}
    };
    return kernel;
}

matrix applyFilter(matrix image, kernel filter) {
    int height = image.size();
    int width = image[0].size();
    int filterHeight = filter.size();
    int filterWidth = filter[0].size();
    matrix newImage(height, vec(width));
    int kCenterX = filterHeight / 2;
    int kCenterY = filterWidth / 2;
    std::cout << "started convolution" << std::endl;
    for (int i = 0; i < height; ++i) {
        for (int j = 0; j < width; ++j) {
            double tmp = 0;
            for (int m = 0; m < filterHeight; ++m) {
                for (int n = 0; n < filterWidth; ++n) {
                    int ii = i + (kCenterY - m);
                    int jj = j + (kCenterX - n);
                    if (ii >= 0 && ii < height && jj >= 0 && jj < width)
                        tmp += image[ii][jj] * filter[m][n];
                }
            }
            if (tmp > 255) {
                tmp = 255;
            }
            else if (tmp < 0) {
                tmp = 0;
            }
            newImage[i][j] = (uint8_t)tmp;
        }
    }
    std::cout << "convolution done" << std::endl;
    return newImage;
}

matrix getImageByFileName(std::string filename, int row)
{
    vec rawFile = readFile(filename);
    matrix image = toMatrix(rawFile, row);
    return image;
}


int main(int argc, char * argv[])
{
    int row = atoi(argv[1]);
    int col = atoi(argv[2]);

    std::string outFile = "result" + std::string(argv[1]) + "_" + std::string(argv[2]) + ".bin";
    std::string inFile = "../labMPI/infile" + std::string(argv[1]) + "_" + std::string(argv[2]) + ".bin";

    matrix inImage = getImageByFileName(inFile, row);
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
    matrix newImage = applyFilter(inImage, getLogKernel());
    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::seconds>(t2 - t1).count();
    std::cout << duration << "s " << std::endl;
    saveImage(outFile, newImage);

    return 0;
}

输入图像为: input.bin

我得到的结果是: output.bin

我在读取图像时通过翻转行/列获得的结果: correctoutput.bin 保存图像而不进行处理将得到与输入相同的图像-因此我的结论是保存工作正常。

1 个答案:

答案 0 :(得分:0)

我想您必须阅读尺寸已替换的图像,因此按宽度移动高度应该可以。