lock&_lock Ответов: 3

Как правильно передать указатель[] или *(указатель+индекс) в таблицу поиска в C ?


Я пытаюсь использовать таблицу поиска для вычисления пикселей в openGL с входным изображением, вот моя таблица поиска :
float  pix_scaling [256];
static void scaling(void)
{
    for (int i = 0; i < 256; i++) 
        pix_scaling[i] = (i * 0.5) + 25;  
 }
Я вызываю обе функции в своем основном цикле, но не могу получить результат вывода, он просто пустой черный и почему-то нет ошибки в терминале.

Что я уже пробовал:

Я вызываю свою таблицу поиска в другой функции :

unsigned char       * image;
unsigned char       * image1;

static void makerShift(){
unsigned char *p, *p1;
float r, g, b;

    if(image1 == NULL) {
        image1 = (unsigned char *)malloc(width*height*4);
        if(image1 == NULL) exit(0);

p  = image;
p1 = image1;

for(int i = 0; i < height*width; i++) {
    r = pix_scaling[p[0]]; // here
    g = pix_scaling[p[1]];
    b = pix_scaling[p[2]];

    //.. other computation process..//

    //to set maximum and minimum pixel value
      if   (r < 0) *(p1+0) = 0;
      else if(r > 255) *(p1+0) = 255;
      else *(p1+0) = r;
        
      if   (g < 0) *(p1+1) = 0;
      else if(g > 255) *(p1+1) = 255;
      else *(p1+1) = g;
        
      if   (b < 0) *(p1+2) = 0;
      else if(b > 255) *(p1+2) = 255;
      else *(p1+2) = b;

      p +=4;
      p1 +=4;
}
Образ исходит из этого :
image = SOIL_load_image("Images/sample.jpg", &width, &height, 0, SOIL_LOAD_RGBA);

Либо я попробовал с указателем
pix_scaling[p[0]];
или указатель и индекс
pix_scaling[*(p+0)];
оба не работают. И без использования pix_scaling , просто
r = (*(p+0) * 0.5) + 25;
g = (*(p+1) * 0.5) + 25; 
b = (*(p+2) * 0.5) + 25; 
вывод изображения пришел нормально, так что я предполагаю, что проблема заключается в моей функции таблицы поиска. Как мне правильно это сделать ?

3 Ответов

Рейтинг:
2

KarstenK

Рик абсолютно прав в том, что вы не всегда получаете доступ к одним и тем же указателям, но вам нужно писать код более тщательно и используйте отладчик- Не промахнись:

unsigned char       * image = NULL;
unsigned char       * image1 = NULL;

Например, не очень хорошо загружать изображение с неполным путем. Всегда проверяйте успех и еще что-нибудь пишите на консоли.

Я бы также определил некоторые структура для получения цветовых данных, с которыми вы можете лучше работать. Когда у вас есть такие структуры вы можете использовать силу C:
pData[n];//access to n-th data element
pData[n].r;//access to the r-value of the n-th data element

совет: отладьте с помощью какой-нибудь очень образцовой картинки, например маленького креста или круга


lock&amp;_lock

- Привет, спасибо. Я действительно проверил загрузчик изображений с помощью этого "if(image == NULL) exit(0);", я не ставлю его в свой вопрос. В моем последнем примере я написал, что этот код работает с вычислением на пиксель внутри цикла (без таблицы поиска), поэтому я знал, что Источник изображения не является проблемой. Я стараюсь, чтобы мой вопрос не был таким длинным. На данный момент я использую структуры для функций заголовочных файлов. Спасибо, я проверю отладчик, я никогда не использую отладчик вне IDE, и на этот раз я нахожусь на терминале, так что я не так хорошо знаком. [Обновление] я установил указатель как нулевой, как вы и предлагали, все та же проблема.

Рейтинг:
13

CPallini

Цитата:
поэтому я предполагаю, что проблема заключается в моей функции таблицы поиска. Как мне правильно это сделать ?
Я не нахожу ничего плохого в вашей таблице масштабирования. Конечно, вы должны инициализировать его (вызов scaling) перед вызовом makeshift.
Примечание Вы назначаете float к unsigned char- Я полагаю, что ваш компилированный предупреждал вас об этом. На самом деле вам вообще не нужно использовать floatдля pix_scaling массив.

[обновление]
Я полагаю, что в коде, который вы не показали, что-то не так.
Следующая программа
#include <stdlib.h>
#include <stdio.h>
float  pix_scaling [256];
static void scaling(void)
{
  for (int i = 0; i < 256; i++)  
    pix_scaling[i] = (i * 0.5) + 25;
}

#define H 4
#define W 4

int main()
{
  unsigned char image[H*W*4];
  unsigned char image_scaled[H*W*4];

  for (int y = 0; y < H; ++y)
  {
    for (int x = 0; x < W; ++x)
    {
      for (int c = 0; c < 3; ++c)
      {
        int i = y* W * 4 + x * 4 + c;
        image[i] = (unsigned char)rand();
      }
    }
  }

  scaling();

  unsigned char *p = image;
  unsigned char *p1 = image_scaled;
  float r,g,b;

  for(int i = 0; i < H*W; i++)
  {
    r = pix_scaling[p[0]]; // here
    g = pix_scaling[p[1]];
    b = pix_scaling[p[2]];

    //to set maximum and minimum pixel value
      if   (r < 0) *(p1+0) = 0;
      else if(r > 255) *(p1+0) = 255;
      else *(p1+0) = r;

      if   (g < 0) *(p1+1) = 0;
      else if(g > 255) *(p1+1) = 255;
      else *(p1+1) = g;

      if   (b < 0) *(p1+2) = 0;
      else if(b > 255) *(p1+2) = 255;
      else *(p1+2) = b;

      p +=4;
      p1 +=4;
  }

  for (int y = 0; y < H; ++y)
  {
    for (int x = 0; x < W; ++x)
    {
      int i = y* W * 4 + x * 4 ;
      printf("(%d,%d), image { %d, %d, %d }, image_scaled {%d, %d, %d}\n", x, y, image[i], image[i+1], image[i+2], image_scaled[i], image_scaled[i+1], image_scaled[i+2]);   

    }
  }

  return 0;
}
производит:
(0,0), image { 103, 198, 105 }, image_scaled {76, 124, 77}
(1,0), image { 115, 81, 255 }, image_scaled {82, 65, 152}
(2,0), image { 74, 236, 41 }, image_scaled {62, 143, 45}
(3,0), image { 205, 186, 171 }, image_scaled {127, 118, 110}
(0,1), image { 242, 251, 227 }, image_scaled {146, 150, 138}
(1,1), image { 70, 124, 194 }, image_scaled {60, 87, 122}
(2,1), image { 84, 248, 27 }, image_scaled {67, 149, 38}
(3,1), image { 232, 231, 141 }, image_scaled {141, 140, 95}
(0,2), image { 118, 90, 46 }, image_scaled {84, 70, 48}
(1,2), image { 99, 51, 159 }, image_scaled {74, 50, 104}
(2,2), image { 201, 154, 102 }, image_scaled {125, 102, 76}
(3,2), image { 50, 13, 183 }, image_scaled {50, 31, 116}
(0,3), image { 49, 88, 163 }, image_scaled {49, 69, 106}
(1,3), image { 90, 37, 93 }, image_scaled {70, 43, 71}
(2,3), image { 5, 23, 88 }, image_scaled {27, 36, 69}
(3,3), image { 233, 94, 212 }, image_scaled {141, 72, 131}

[/обновление]


Rick York

Я тоже это видел и отметил в комментарии к своему посту выше. Я думаю, что это, скорее всего, и есть причина проблемы.

CPallini

Мы должны были указать на такой дефект (я пропустил ваше замечание), но я считаю, что он вряд ли является причиной проблемы.

Rick York

Неужели? Вы, конечно, можете быть правы. Это трудно угадать без всего кода. Если мне станет скучно в эти выходные, я могу написать какой-нибудь код, чтобы проверить это. Мне довольно любопытно посмотреть, что происходит.

lock&amp;_lock

- Привет, спасибо. Да, я действительно называю масштабирование перед импровизацией. Кроме того, я ответил на комментарий Рика (с моим скриншотом терминала). Даже после попытки округлить или бросить p[0], p[1] и p[2] значение все равно равно нулю.

CPallini

Смотрите мое обновленное решение.

lock&amp;_lock

Я потратил 20 минут на сравнение с вашим ответом, это точно такой же подход. Что не так с моим кодом? Позвольте мне взглянуть еще раз :(

lock&amp;_lock

Я даже распечатал значение масштабирования внутри таблицы поиска, и это значение является правильным. Но в функции он все равно равен нулю.

CPallini

Не могли бы вы опубликовать больше соответствующего кода?

lock&amp;_lock

Вот оно : https://gist.github.com/raisa0890/9b86a59a02f8441a677709f59bedff8a

CPallini

В коде github я вижу, что в самый первый раз, когда ваш код вызывает makeShift (в основном тексте), массив pix_scaling еще не инициализирован (пока нет вызова масштабирования).

lock&amp;_lock

Привет, спасибо !! Я инициализировал в своем mainloop, но почему - то забыл инициализировать в своей основной программе. Во всяком случае, я инициализировал его, но все равно та же проблема. Странно, как я на самом деле так долго работал над этим 3 дня.

lock&amp;_lock

О, большое спасибо ! После попытки отладки он теперь работает. Большое спасибо

CPallini

Добро пожаловать.

Рейтинг:
12

Rick York

Мне кажется, что проблема здесь :

r = pix_scaling[p[0]];
g = pix_scaling[p[1]];
b = pix_scaling[p[2]];
r, g, b всегда будут иметь одни и те же значения, потому что p[1] - это никогда не изменяющийся a. Я думаю, что вы должны увеличивать p, чтобы указать на следующий пиксель на каждой итерации цикла.


lock&amp;_lock

Привет @Rick, спасибо ! Я увеличил p и p1, мой код был частью еще более длинного кода, и я забыл поставить здесь. Я обновил свой вопрос. Это все та же проблема.

Rick York

OK, I would try to do some careful debugging. You don't even need the debugger if that's a problem but it would make things easier. I would change the loop to just check the first four or five pixels. Add printfs to output the values at each step along the way: what is p[0], p[1], and p[2] to start. Then display what the values of r, g, and b are. Lastly, what are p1[0], p1[1], and p1[2] after the assignment. This should help you identify where the problem is. It appears to me that the assignments could be a problem. You have *(p1+0) = r; as an assignment statement. That is assigning a float to a UCHAR value. You might need a cast or rounding operation there to get a UCHAR from it. Regardless, printing out the values at each step will help you figure out where your problem is.

lock&amp;_lock

Привет, Рик, я попытался вывести значение на терминал. так что p[0], p[1] и p[2] выглядят нормально (вот терминал screnshot : https://i.imgur.com/08VtQQ2.png) но после функции таблицы поиска R, G, B равны нулю. Даже если я округлю p[0], p [1] и p[2] или приведу их до того, как введу в функцию, результат все равно будет равен нулю. Итак, вы правы, это проблема назначения. Я буду искать его еще.

CPallini

У меня 5.