T
T
tj572018-10-28 21:19:19
C++ / C#
tj57, 2018-10-28 21:19:19

How to draw a line with Bresenham's algorithm and gamma correction on a text file?

Есть задача - создать текстовый файл формата .pgm или .ppm и заполнить его значениями = 255, чтобы получилось просто пустое изображение с белым фоном (размер задаётся при создании). Затем сделать функцию, с помощью которой можно отрисовать черную линию с произвольными координатами, которые задаются пользователем (я выбрал алгоритм Брезенхема). В итоге в текстовом файле сохраняется линия такого вида:
5bd5fae59bb15314855816.png
Теперь стоит задача нарисовать "красивую" линию, которая не будет выглядеть ступенчато, а просто как обычная ровная линия. Препод предлагает использовать гамма-коррекцию, а именно переводить каждый пиксель по такой формуле : encoded = ((original / 255) ^ (1 / gamma)) * 255
Также советует смотреть в сторону стандарта sRGB.
В первую очередь интересует, каковы значения переменных original и gamma? Во-вторых, как именно здесь должен применяться sRGB ? И для отрисовки "красивой" линии мне нужно просто каждый пиксель линии переводить по такой формуле ?
Код программы :

#include "stdafx.h"

#include <iostream> 

#include <iomanip>

#include <fstream> 

#include <sstream>

using namespace std;

void drawLine(int** array, int x1, int y1, int x2, int y2) {
  const int deltaX = abs(x2 - x1);
  const int deltaY = abs(y2 - y1);
  const int signX = x1 < x2 ? 1 : -1;
  const int signY = y1 < y2 ? 1 : -1;
  //
  int error = deltaX - deltaY;
  //
  array[x2][y2] = 0;
  
  while (x1 != x2 || y1 != y2)
  {
    array[x1][y1] = 0;
    const int error2 = error * 2;
    //
    if (error2 > -deltaY)
    {
      error -= deltaY;
      x1 += signX;
    }
    if (error2 < deltaX)
    {
      error += deltaX;
      y1 += signY;
    }
  }

}


int main(void)
{
  ofstream fout;
  
  fout.open("E:\\line.pgm");

  fout.write("", 0);

  fout « "P2" « "\n" ;

  int numcols, numrows, x1, x2, y1, y2;

  cout « "Enter rows and columns number: ";

  cin » numrows » numcols;

  cout « "Enter coords x1 and y1: ";

  cin » x1 » y1;

  cout « "Enter coords x2 and y2: ";

  cin » x2 » y2;

  fout « numrows « " " « numcols « "\n";

  fout « 255 « "\n";

  int** array = new int*[numrows];

  for (int count = 0; count < numrows; count++)

    array[count] = new int[numcols];

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

    for (int j = 0; j < numcols; ++j) {
       array[i][j] = 255;
    }

  }

  drawLine(array, x1, y1, x2, y2);

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

    for (int j = 0; j < numcols; ++j) {
      fout « array[i][j] « " ";
    }

  }

  fout.close();

}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2018-10-29
@Mercury13

Я бы работал по такой формуле:
result = ((original / max)1 / gamma) · 255
Original — это полученное алгоритмом Ву значение (float или хотя бы short!)
max — максимально возможное значение original. Для short, например, это 65535.
gamma — традиционно 2,2.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question