【问题标题】:Convert PPM Image to Greyscale C++将 PPM 图像转换为灰度 C++
【发布时间】:2015-03-08 06:14:37
【问题描述】:

尝试通过索引包含像素数据的指针将 PPM 图像转换为灰度:

void PPMObject::greyScale()
{
    const float r = 0.299F;
    const float g = 0.587F;
    const float b = 0.114F;

    int size = this->width * this->height * 3;
    for (int i = 0; i < size; i++)
    {
        this->m_Ptr[i] = (this->m_Ptr[i] * r) + (this->m_Ptr[i] * g) + (this->m_Ptr[i] * b);
        this->m_Ptr[i+1] = (this->m_Ptr[i+1] * r) + (this->m_Ptr[i+1] * g) + (this->m_Ptr[i+1] * b);
        this->m_Ptr[i+2] = (this->m_Ptr[i+2] * r) + (this->m_Ptr[i+2] * g) + (this->m_Ptr[i+2] * b);
    }
}

我使用 >> 重载读取了 PPM 图像文件:

istream& operator >>(istream &inputStream, PPMObject &other)
{
    inputStream >> other.magicNum >> other.width >> other.height >> other.maxColorValue;
    inputStream.get();
    size_t size = other.width * other.height * 3;
    other.m_Ptr = new char[size];
    inputStream.read(other.m_Ptr, size);
    return inputStream;
}

我写数据如下:

ostream& operator <<(ostream &outputStream, const PPMObject &other)
{
    outputStream << other.magicNum  << " "
    << other.width          << " "
    << other.height         << " "
    << other.maxColorValue  << " "
    ;   
    outputStream.write(other.m_Ptr, other.width * other.height * 3);
    return outputStream;
}

读取或写入 PPM 文件没有问题。

问题只是将 PPM 图像转换为灰度 - 索引不是方法。该文件未更改。

问题很可能是:如何从指针中获取值来操作它们?

例如,char 指针中的像素在哪里?

平均 RGB 分量值当然是另一种方法,但是如何将平均值分配回指针?

【问题讨论】:

    标签: c++ pointers grayscale ppm


    【解决方案1】:

    在您的 grayScale() 函数中,每次您通过循环时,您需要将 i 增加 3,因为每个像素占用 3 个字节并且您一次处理一个像素:

    for (int i = 0; i < size; i+=3)
    

    此外,您当前使用的公式将使值保持不变(忽略舍入和浮点错误)。

    这个:

    this->m_Ptr[i] = (this->m_Ptr[i] * r) + (this->m_Ptr[i] * g) + (this->m_Ptr[i] * b);
    

    简化为:

     this->m_Ptr[i] = (this->m_Ptr[i] * 1.0F);
    

    正确的公式是这样的(忽略强制转换并假设数据是 RGB 顺序):

    for (int i = 0; i < size; i+=3)
    {
        float greyscaleValue = (this->m_Ptr[i] * r) + (this->m_Ptr[i+1] * g) + (this->m_Ptr[i+2] * b);
        this->m_Ptr[i] = greyscaleValue;
        this->m_Ptr[i+1] = greyscaleValue;
        this->m_Ptr[i+2] = greyscaleValue;
    }
    

    【讨论】:

    • 谢谢!有了更多的经验,我应该自己发现这些错误。
    【解决方案2】:

    我今天早些时候编写的以下程序成功地将彩色图像 (.ppm) 文件转换为灰度图像 (​​.ppm) 文件。我添加了很多 cmets,以便您轻松跟进。

    #include <fstream>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main() {
        //File input and output streams
        ifstream fin("colorImage.ppm");
        ofstream fout("grayscaleImage.ppm");
        //Check if input file was successfully opened
        if (!fin) {
            cout << "Error - Nonexistent Image (.ppm) File" << endl;
            system("pause");
            return -1;  // Error exit
        }
        //Declare necessary variables
        string magic_number;
        int pixel_per_row, num_rows, color_depth, red, green, blue;
        //Read in values for the following variables from input file
        fin >> magic_number >> pixel_per_row >> num_rows >> color_depth;
        //Write the following variables to the output file
        fout << magic_number << endl << pixel_per_row << " " << num_rows << endl << color_depth << endl;
        //Read in input file until file end putting values into appropriate variables
        while (fin >> red >> green >> blue) {
            red = green = blue = int(0.3 * red + 0.59 * green + 0.11 * blue); //Covert each pixel to grayscale
            fout << red << endl << green << endl << blue << endl; //Write converted values to output file
        }
        //Close files
        fin.close();
        fout.close();
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多