【问题标题】:Resize volume file length and width in C++在 C++ 中调整卷文件的长度和宽度
【发布时间】:2016-10-11 23:15:55
【问题描述】:

我有一个卷文件,其切片长度可变,图像高度为 640,图像宽度为 512。我想将其转换为高度为 620,宽度为 420 的文件,并将其写入新的文件。我想从高度的顶部取出 20 个像素,并从宽度的每一侧取出 46 个像素来调整大小。每个像素都是无符号的 16 位。我不确定如何进行实际操作。

这是我的主要内容:

FILE* pfile = NULL;
FILE* pfile2 = NULL;

pFile = fopen("test.vol", "rb");
fseek (pFile , 0 , SEEK_END);

int fileData = ftell(pFile);
rewind(pFile);

char* FileBuffer = new char[fileData];
fread(FileBuffer, fileData, 1, pFile);

int height = 640;
int width = 512;
int slizeSize = height * width * 2;
int sliceCount = fileData / sliceSize;
uint16_t pixels;

int newHeight = height - 20;
int newWidth = width - 92;
int newSliceSize = newHeight * newWidth * 2;
int newImageSize = newSliceSize * sliceCount;

char* NewFileBuffer = new char[newImageSize];

for (int i = 0; i < newHeight; i++) {

    for (int i = 0; i < newWidth; i++) {

    }
   // need help in these for loops and after

}

fclose (pFile);
free (FileBuffer);

pFile2 = fopen("test2.vol", "wb");
fwrite(NewFileBuffer, NewImageSize, 1, pFile2);

【问题讨论】:

    标签: c++ image-processing


    【解决方案1】:

    如果您使用 C++ 编程,请使用 C++:摆脱 FILE* 和其他 C 内容。

    您正在分配charnew 的数组,但调用free 来释放内存:您应该调用delete[],或者更好的是您应该使用std::vector 并让它为您管理内存.

    您正在处理 16 位值,那么为什么不读取/写入/处理 16 位值呢?

    首先,读取文件:

    #include <fstream>
    #include <iterator>
    #include <vector>
    
    int main()
    {
        using data_type = uint16_t;
    
        std::basic_ifstream<data_type> file_in{
            "test.vol",
            std::ifstream::binary
        };
        std::vector<data_type> FileBuffer{
            std::istreambuf_iterator<data_type>(file_in), 
            std::istreambuf_iterator<data_type>() // end of stream iterator
        };
    

    现在FileBuffer 是一个由uint16_t 组成的数组,其中填充了"test.vol" 的内容,具有托管内存分配和释放。

    下一部分,调整音量。我假设您的数据按以下顺序打包:列、行、切片。目前尚不清楚顶部是切片的第一行还是最后一行。这是我使用迭代器和std::copy 的提议:

        size_t height = 640, width = 512;
        size_t sliceSize = height * width;
        size_t sliceCount = FileBuffer.size() / sliceSize;
    
        size_t newHeight = height - 20, newWidth = width - 92;
        size_t newSliceSize = newHeight * newWidth;
        size_t newImageSize = newSliceSize * sliceCount;
    
        std::vector<data_type> NewFileBuffer(newImageSize);
    
        auto it_buffer = FileBuffer.begin();
        auto it_new_buffer = NewFileBuffer.begin();
    
        for (size_t i = 0; i < sliceCount; ++i)
        {
            // skip 20 first lines, remove and uncomment the next line
            // if you want to skip the last ones
            auto it_line = it_buffer + 20*width;
            //auto it_line = it_buffer;
    
            for (size_t j = 0; j < newHeight; ++j)
            {
                auto it_column = it_line + 46;
    
                it_new_buffer = std::copy(
                    it_column,
                    it_column + newWidth,
                    it_new_buffer
                );
    
                it_line += width; // go to next line
            }
    
            it_buffer += sliceSize; // go to next slice
        }
    

    最后,写入文件:

        std::basic_ofstream<data_type> file_out{
            "test2.vol",
            std::ofstream::binary
        };
        std::copy(
            NewFileBuffer.begin(),
            NewFileBuffer.end(),
            std::ostreambuf_iterator<data_type>(file_out)
        );
    }
    

    【讨论】:

    • 谢谢,但是当我编译这个时我得到了很多错误。错误:“data_type”之前的预期嵌套名称说明符似乎导致了错误的连锁反应
    • 我尝试在 c++ 11 和 98 中编译,但仍然出现错误
    • 好的,我修复了这个错误。现在我得到“在抛出 'std::bad_cast' what() 的实例后调用终止:std::bad_cast Aborted (core dumped)”
    • 代码确实是c++11。你是如何修复错误的?哪个电话正在抛出?
    • 我将 using data_type uint16_t; 更改为 using data_type = uint16_t;. 我尝试使用 gdb 来调试程序,但它没有给我一个关于它有问题的线索
    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2015-10-24
    • 1970-01-01
    相关资源
    最近更新 更多