0

I have wrong output values :(

:( edges correctly filters middle pixel
    expected "210 150 60\n", not "210 32 203\n"
:( edges correctly filters pixel on edge
    expected "213 228 255\n", not "213 228 166\n"
:( edges correctly filters pixel in corner
    expected "76 117 255\n", not "76 117 162\n"
:( edges correctly filters 3x3 image
    expected "76 117 255\n21...", not "76 117 162\n21..."
:( edges correctly filters 4x4 image
    expected "76 117 255\n21...", not "76 117 162\n21..."

Some of them are correct (color channels), but others are not, I'm not sure why.

code:

#include "helpers.h"
#include <math.h>


RGBTRIPLE calculate_sum_of_squered_Gx_and_GY(RGBTRIPLE Gx_sum, RGBTRIPLE Gy_sum, int cap_value);
RGBTRIPLE trim_channel_to_max_value(RGBTRIPLE Gxsq_Gysq, int cap_value);
RGBTRIPLE pass_value_to_temp_image_px(RGBTRIPLE temp_image_px, RGBTRIPLE value);
RGBTRIPLE refresh_values_to_0();
RGBTRIPLE count_G_sum(int h_px, int w_px, int im_height, int im_width, RGBTRIPLE image[im_height][im_width], int rows, int cols, int G_Matrix[rows][cols]);

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    const int HEX_W = 3;
    const int HEX_H = 3;

    int Gx_Matrix[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int Gy_Matrix[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    RGBTRIPLE Gx_sum, Gy_sum, Gxsq_Gysq;

    const int cap_value = 255;

    RGBTRIPLE temp_image[height][width];

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            // take values from all sticking nearby channels to Gx && Gy
            Gx_sum = count_G_sum(i, j, height, width, image, 3, 3, Gx_Matrix);
            Gy_sum = count_G_sum(i, j, height, width, image, 3, 3, Gy_Matrix);

            Gxsq_Gysq = calculate_sum_of_squered_Gx_and_GY(Gx_sum, Gy_sum, cap_value);

            temp_image[i][j] = pass_value_to_temp_image_px(temp_image[i][j], Gxsq_Gysq);

            Gxsq_Gysq = refresh_values_to_0();
            Gy_sum = refresh_values_to_0();
            Gx_sum = refresh_values_to_0();
        }
    }

    // pass channels values from temp image to original image
    for (int m = 0; m < height; m++)
    {
        for (int o = 0; o < width; o++)
        {
            image[m][o].rgbtRed = temp_image[m][o].rgbtRed;
            image[m][o].rgbtGreen = temp_image[m][o].rgbtGreen;
            image[m][o].rgbtBlue = temp_image[m][o].rgbtBlue;
        }
    }
}

RGBTRIPLE count_G_sum(int h_px, int w_px, int im_height, int im_width, RGBTRIPLE image[im_height][im_width], int rows, int cols, int G_Matrix[rows][cols])
{
    RGBTRIPLE G_sum;
    G_sum.rgbtRed = 0;
    G_sum.rgbtGreen = 0;
    G_sum.rgbtBlue = 0;

    for (int h = 0; h < 3; h++)
    {
        if (h_px - 1 + h >= 0 && h_px - 1 + h < im_height)
        {
            for (int w = 0; w < 3; w++)
            {
                if (w_px - 1 + w >= 0 && w_px - 1 + w < im_width)
                {
                    G_sum.rgbtRed += image[h_px - 1 + h][w_px - 1 + w].rgbtRed * G_Matrix[h][w];
                    G_sum.rgbtGreen += image[h_px - 1 + h][w_px - 1 + w].rgbtGreen * G_Matrix[h][w];
                    G_sum.rgbtBlue += image[h_px - 1 + h][w_px - 1 + w].rgbtBlue * G_Matrix[h][w];
                }
            }
        }
    }

    return G_sum;
}

RGBTRIPLE calculate_sum_of_squered_Gx_and_GY(RGBTRIPLE Gx_sum, RGBTRIPLE Gy_sum, int cap_value)
{
    RGBTRIPLE Gxsq_Gysq;

    // calculating squared sum of matrixes
    Gxsq_Gysq.rgbtRed = round( sqrtf( pow(Gx_sum.rgbtRed, 2) + pow(Gy_sum.rgbtRed, 2)));
    Gxsq_Gysq.rgbtGreen = round( sqrtf( pow(Gx_sum.rgbtGreen, 2) + pow(Gy_sum.rgbtGreen, 2)));
    Gxsq_Gysq.rgbtBlue = round( sqrtf( pow(Gx_sum.rgbtBlue, 2) + pow(Gy_sum.rgbtBlue, 2)));

    Gxsq_Gysq = trim_channel_to_max_value(Gxsq_Gysq, cap_value);

    return Gxsq_Gysq;
}

RGBTRIPLE trim_channel_to_max_value(RGBTRIPLE Gxsq_Gysq, int cap_value)
{

    if (Gxsq_Gysq.rgbtRed > cap_value)
    {
        Gxsq_Gysq.rgbtRed = cap_value;
    }
    if (Gxsq_Gysq.rgbtGreen > cap_value)
    {
        Gxsq_Gysq.rgbtGreen = cap_value;
    }
    if (Gxsq_Gysq.rgbtBlue > cap_value)
    {
        Gxsq_Gysq.rgbtBlue = cap_value;
    }

    return Gxsq_Gysq;
}

RGBTRIPLE pass_value_to_temp_image_px(RGBTRIPLE temp_image_px, RGBTRIPLE value)
{
    temp_image_px.rgbtRed = value.rgbtRed;
    temp_image_px.rgbtGreen = value.rgbtGreen;
    temp_image_px.rgbtBlue = value.rgbtBlue;

    return temp_image_px;
}

RGBTRIPLE refresh_values_to_0()
{
    RGBTRIPLE target_file;

    target_file.rgbtRed = 0;
    target_file.rgbtGreen = 0;
    target_file.rgbtBlue = 0;

    return target_file;
}

Also fact that I can't get output image for some weird reason doesn't help either.

Thanks in advance for any help.

2 Answers 2

4

You are using 'RGBTRIPLE' structs along your code which is kind of neat but it comes with some issues:

  • That struct only can store values from 0 to 255 with no decimal point. That means that when doing calculations that could result in numbers with decimal point, the decimal part will be truncated, no matter if it's 0.1 or 0.9.

  • The other issue derivated from the previos point, is that calling: RGBTRIPLE trim_channel_to_max_value(RGBTRIPLE Gxsq_Gysq, int cap_value) won't have any effect. If the value is more than 255 will have been overlapped when assigned to 'RGBTRIPLE' struct, before calling the trim function.

2
  • Thanks man! It worked!
    – Lukkar
    May 14, 2020 at 9:54
  • Beautiful !! Do not put any value which exceeds the limits that type of variable can store. Feb 24, 2021 at 10:33
0

Updated code according @Tritum suggestions. I've created RGB_s_INT struck in the place of RGBTRIPLE structs, where values should not be limited by BYTE type (int type is not limited to 255 value).

#include "helpers.h"
#include <math.h>

// temp struct to store in higher than 255
typedef struct
{
    int rgbtBlue_int;
    int rgbtGreen_int;
    int rgbtRed_int;
}
RGB_S_INT;

RGB_S_INT count_G_sum(int h_px, int w_px, int im_height, int im_width, RGBTRIPLE image[im_height][im_width], int rows, int cols,
                      int G_Matrix[rows][cols]);

RGB_S_INT calculate_sum_of_squered_Gx_and_GY(RGB_S_INT Gx_sum, RGB_S_INT Gy_sum, int cap_value);
RGB_S_INT trim_channel_to_max_value(RGB_S_INT Gxsq_Gysq, int cap_value);
RGBTRIPLE pass_value_to_temp_image_px(RGB_S_INT value);
RGB_S_INT refresh_values_to_0();

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    // size of G's Matrix
    const int HEX_W = 3;
    const int HEX_H = 3;

    int Gx_Matrix[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int Gy_Matrix[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    RGB_S_INT Gx_sum, Gy_sum, Gxsq_Gysq;

    const int cap_value = 255;

    RGBTRIPLE temp_image[height][width];

    // iterating through all pixels in image
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            // take values from all sticking nearby channels to Gx && Gy
            Gx_sum = count_G_sum(i, j, height, width, image, 3, 3, Gx_Matrix);
            Gy_sum = count_G_sum(i, j, height, width, image, 3, 3, Gy_Matrix);

            Gxsq_Gysq = calculate_sum_of_squered_Gx_and_GY(Gx_sum, Gy_sum, cap_value);

            temp_image[i][j] = pass_value_to_temp_image_px(Gxsq_Gysq);

            Gxsq_Gysq = refresh_values_to_0();
            Gy_sum = refresh_values_to_0();
            Gx_sum = refresh_values_to_0();
        }
    }

    // pass channels values from temp image to original image
    for (int m = 0; m < height; m++)
    {
        for (int o = 0; o < width; o++)
        {
            image[m][o].rgbtRed = temp_image[m][o].rgbtRed;
            image[m][o].rgbtGreen = temp_image[m][o].rgbtGreen;
            image[m][o].rgbtBlue = temp_image[m][o].rgbtBlue;
        }
    }
}

RGB_S_INT count_G_sum(int h_px, int w_px, int im_height, int im_width, RGBTRIPLE image[im_height][im_width], int rows, int cols,
                      int G_Matrix[rows][cols])
{
    // RGB channels sums
    RGB_S_INT G_sum;
    G_sum.rgbtRed_int = 0;
    G_sum.rgbtGreen_int = 0;
    G_sum.rgbtBlue_int = 0;

    // iterating through matrix around inputed reference image px
    for (int h = 0; h < 3; h++)
    {
        if (h_px - 1 + h >= 0 && h_px - 1 + h < im_height)
        {
            for (int w = 0; w < 3; w++)
            {
                if (w_px - 1 + w >= 0 && w_px - 1 + w < im_width)
                {
                    // assign values to struck
                    G_sum.rgbtRed_int += image[h_px - 1 + h][w_px - 1 + w].rgbtRed * G_Matrix[h][w];
                    G_sum.rgbtGreen_int += image[h_px - 1 + h][w_px - 1 + w].rgbtGreen * G_Matrix[h][w];
                    G_sum.rgbtBlue_int += image[h_px - 1 + h][w_px - 1 + w].rgbtBlue * G_Matrix[h][w];
                }
            }
        }
    }

    return G_sum;
}

RGB_S_INT calculate_sum_of_squered_Gx_and_GY(RGB_S_INT Gx_sum, RGB_S_INT Gy_sum, int cap_value)
{
    RGB_S_INT Gxsq_Gysq;

    // calculating squared sum of matrixes
    Gxsq_Gysq.rgbtRed_int = round(sqrtf(pow(Gx_sum.rgbtRed_int, 2) + pow(Gy_sum.rgbtRed_int, 2)));
    Gxsq_Gysq.rgbtGreen_int = round(sqrtf(pow(Gx_sum.rgbtGreen_int, 2) + pow(Gy_sum.rgbtGreen_int, 2)));
    Gxsq_Gysq.rgbtBlue_int = round(sqrtf(pow(Gx_sum.rgbtBlue_int, 2) + pow(Gy_sum.rgbtBlue_int, 2)));

    Gxsq_Gysq = trim_channel_to_max_value(Gxsq_Gysq, cap_value);

    return Gxsq_Gysq;
}

RGB_S_INT trim_channel_to_max_value(RGB_S_INT Gxsq_Gysq, int cap_value)
{
    // cap value is equal to max value of each color channel
    if (Gxsq_Gysq.rgbtRed_int > cap_value)
    {
        Gxsq_Gysq.rgbtRed_int = cap_value;
    }
    if (Gxsq_Gysq.rgbtGreen_int > cap_value)
    {
        Gxsq_Gysq.rgbtGreen_int = cap_value;
    }
    if (Gxsq_Gysq.rgbtBlue_int > cap_value)
    {
        Gxsq_Gysq.rgbtBlue_int = cap_value;
    }

    return Gxsq_Gysq;
}

RGBTRIPLE pass_value_to_temp_image_px(RGB_S_INT value)
{
    RGBTRIPLE temp_image_px;

    temp_image_px.rgbtRed = value.rgbtRed_int;
    temp_image_px.rgbtGreen = value.rgbtGreen_int;
    temp_image_px.rgbtBlue = value.rgbtBlue_int;

    return temp_image_px;
}

RGB_S_INT refresh_values_to_0()
{
    RGB_S_INT target_file;

    target_file.rgbtRed_int = 0;
    target_file.rgbtGreen_int = 0;
    target_file.rgbtBlue_int = 0;

    return target_file;
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .