2015-03-08 4 views
1

Попытка преобразовать PPM изображения в оттенки серого путем индексации указатель, содержащий пиксельные данные:Преобразование PPM изображения в Greyscale C++

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); 
    } 
} 

Где я прочитал файл изображения РРМ с помощью >> перегрузки:

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 - это, безусловно, другой подход, но как я могу назначить среднее значение обратно в указатель?

ответ

2

Внутри вашего 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; 
} 
+0

Спасибо ! С большим опытом я должен сам поймать эти ошибки. – user4640007

Смежные вопросы