将 PPM 图像转换为灰度 C++
Convert PPM Image to Greyscale C++
正在尝试通过索引包含像素数据的指针将 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 图像转换为灰度 -- 索引不是方法。该文件未更改。
问题很可能是:如何从指针获取值来操作它们?
例如,字符指针中的像素位于何处?
平均 RGB 分量值当然是另一种方法,但是我如何将平均值分配回指针?
在您的 greyScale() 函数中,您需要在每次执行循环时将 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;
}
我今天早些时候编写的以下程序成功地将彩色图像 (.ppm) 文件转换为灰度图像 (.ppm) 文件。我添加了很多评论,以便您可以轻松跟进。
#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;
}
正在尝试通过索引包含像素数据的指针将 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 图像转换为灰度 -- 索引不是方法。该文件未更改。
问题很可能是:如何从指针获取值来操作它们?
例如,字符指针中的像素位于何处?
平均 RGB 分量值当然是另一种方法,但是我如何将平均值分配回指针?
在您的 greyScale() 函数中,您需要在每次执行循环时将 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;
}
我今天早些时候编写的以下程序成功地将彩色图像 (.ppm) 文件转换为灰度图像 (.ppm) 文件。我添加了很多评论,以便您可以轻松跟进。
#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;
}