my apologies for sloppy code or an incorrectly formatted question, its my first post!
the basic gist of this block of code is to apply edge detection with the sobel operator. i have a for loop nested in a for loop to iterate through the individual pixels and another nested for loop to iterate through a smaller 2D array to apply the sobel operator, but the last line of pixels and some of the right edge arent resolving correctly. many thanks!
#include <math.h>
#include "helpers.h"
//prototype functions
void calcVert (int h, int w, int height, int width, RGBTRIPLE temp[height][width], int *blue, int *green, int *red);
void calcHori (int h, int w, int height, int width, RGBTRIPLE temp[height][width], int *blue, int *green, int *red);
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
int sobelBlueV;
int sobelGreenV;
int sobelRedV;
int sobelBlueH;
int sobelGreenH;
int sobelRedH;
RGBTRIPLE temp[height][width];
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
temp[h][w].rgbtBlue = image[h][w].rgbtBlue;
temp[h][w].rgbtGreen = image[h][w].rgbtGreen;
temp[h][w].rgbtRed = image[h][w].rgbtRed;
}
}
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
/*
[-1] [0] [+1] [+1] [+2] [+1]
[-2] [0] [+2] [0 ] [0 ] [0 ]
[-1] [0] [+1] [-1] [-2] [-1]
*/
calcVert(h, w, height, width, temp, &sobelBlueV, &sobelGreenV, &sobelRedV);
calcHori(h, w, height, width, temp, &sobelBlueH, &sobelGreenH, &sobelRedH);
// ^2 and sqrt
int bluePoint = round(sqrt(pow(sobelBlueV, 2) + pow(sobelBlueH, 2)));
if (bluePoint > 255) bluePoint = 255;
int GreenPoint = round(sqrt(pow(sobelGreenV, 2) + pow(sobelGreenH, 2)));
if (GreenPoint > 255) GreenPoint = 255;
int RedPoint = round(sqrt(pow(sobelRedV, 2) + pow(sobelRedH, 2)));
if (RedPoint > 255) RedPoint = 255;
image[h][w].rgbtBlue = bluePoint;
image[h][w].rgbtGreen = GreenPoint;
image[h][w].rgbtRed = RedPoint;
}
}
}
void calcVert (int h, int w, int height, int width, RGBTRIPLE temp[height][width], int *blue, int *green, int *red)
{
//row 1: [-1] [0] [+1]
//row 2: [-2] [0] [+2]
//row 3: [-1] [0] [+1] vertical kernel
int cellCalc = 0;
int totalRed = 0;
int totalBlue = 0;
int totalGreen = 0;
//row 1
for (int relativeH = -1; relativeH <= 1; relativeH++)
{
for (int relativeW = -1; relativeW <= 1; relativeW++)
{
//overreach cases
if (h + relativeH < 0 && w + relativeW < 0)//top left corner
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
if (relativeH == 0 && relativeW ==1) cellCalc = 2;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (h + relativeH < 0 && w + relativeW >= width)//top right corner
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = -2;
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = -1;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0 && relativeW ==1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (h + relativeH < 0)//top edge
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = -2;
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = -1;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
if (relativeH == 0 && relativeW ==1) cellCalc = 2;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW < 0 && h + relativeH >= height)//bottom left corner
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 1;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0 && relativeW ==1) cellCalc = 2;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW < 0)//left edge
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 1;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
if (relativeH == 0 && relativeW ==1) cellCalc = 2;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (h + relativeH >= height && w + relativeW >= width)//bottom right corner
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = -2;
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0 && relativeW ==1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW >= width)//right edge
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = -2;
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == 1 && relativeW == -1) cellCalc = -1;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0 && relativeW ==1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else //valid cases
{
//set cell values
if (relativeH == 0 && relativeW == -1) cellCalc = -2;
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == 1 && relativeW == -1) cellCalc = -1;
if (relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 1;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
if (relativeH == 0 && relativeW ==1) cellCalc = 2;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
}
}
}
void calcHori (int h, int w, int height, int width, RGBTRIPLE temp[height][width], int *blue, int *green, int *red)
{
//row 1: [+1] [+2] [+1]
//row 2: [ 0] [ 0] [ 0]
//row 3: [-1] [-2] [-1]
int cellCalc = 0;
int totalRed = 0;
int totalBlue = 0;
int totalGreen = 0;
//row 1
for (int relativeH = -1; relativeH <= 1; relativeH++)
{
for (int relativeW = -1; relativeW <= 1; relativeW++)
{
//overreach cases
if (h + relativeH < 0 && w + relativeW < 0)//top left corner
{
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
}
else if (h + relativeH < 0 && w + relativeW >= width)//top right corner
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 1;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (h + relativeH < 0)//top edge
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == 0) cellCalc = 0;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 1;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW < 0 && h + relativeH >= height)//bottom left corner
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == 0) cellCalc = -2;
if (relativeH == -1 && relativeW == 1) cellCalc = -1;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW < 0)//left edge
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = 0;
if (relativeH == -1 && relativeW == 0) cellCalc = -2;
if (relativeH == -1 && relativeW == 1) cellCalc = -1;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (h + relativeH >= height && w + relativeW >= width)//bottom right corner
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == -1 && relativeW == 0) cellCalc = -2;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 0;
if (relativeH == 1 && relativeW == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else if (w + relativeW >= width)//right edge
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == -1 && relativeW == 0) cellCalc = -2;
if (relativeH == -1 && relativeW == 1) cellCalc = 0;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 1;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 0;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
else //valid cases
{
//set cell values
if (relativeH == -1 && relativeW == -1) cellCalc = -1;
if (relativeH == -1 && relativeW == 0) cellCalc = -2;
if (relativeH == -1 && relativeW == 1) cellCalc = -1;
if (relativeH == 0) cellCalc = 0;
if (relativeH == 1 && relativeW == -1) cellCalc = 1;
if (relativeH == 1 && relativeW == 0) cellCalc = 2;
if (relativeH == 1 && relativeW == 1) cellCalc = 1;
totalBlue += ((temp[h + relativeH][w + relativeW].rgbtBlue) * cellCalc);
totalGreen += ((temp[h + relativeH][w + relativeW].rgbtGreen) * cellCalc);
totalRed += ((temp[h + relativeH][w + relativeW].rgbtRed) * cellCalc);
*blue = totalBlue;
*green = totalGreen;
*red = totalRed;
}
}
}
}
Your code is indeed complicated and due to the number of tests per pixel, pretty inefficient. I strongly advise you to rewrite the function with the following structure:
processing of the first line;
processing loop on the inner rows;
processing of the last row;
and for every row
processing of the first pixel;
processing loop on the inner columns;
processing of the last pixel.
For application of the kernels, do not use a double loop but hard-code the formula (there are actually six terms, not nine). Splitting the processing in nine instances allows you to cleanly specialize the code on the borders.
To avoid the repetitions for the RGB components, you may use helper functions, with some hope that they will be inlined by the compiler.