问题描述:

I'm working on my task in computer vision course. One of sub-tasks is gradient direction computation based on image brightness. I've made a matrix bright[width][height] containing brightness values for every pixel of the image. And i have two such functions:

`double Image::grad_x(int x,int y){`

if(x==width-1 || x==0) return bright[x][y];

return bright[x+1][y]-bright[x-1][y];

}

double Image::grad_y(int x,int y){

if(y==height-1 || y==0) return bright[x][y];

return bright[x][y+1]-bright[x][y-1];

}

EDIT: border check fixed

I'm working with simple derivative, without using Sobel operator 'cause simple derivative is sufficient for my needs.

The question is, am i doing this gradient computation right and what exactly do i have to do with border pixels(right now function returns value of the pixel itself, im not sure it's accurate)? And, by the way, is there any utility for computation of gradients of the image? I want to be sure my program is performing well.

Your computation is correct. It is a simple gradient method you're using, but if that's fine for your use there is nothing wrong with that.

The corner cases are a problem because you don't have enough data to calculate a gradient in the same way as the other pixels. One way to deal with them is to simply not calculate the corner cases and live with a slightly smaller image.

If this is not an option you can also extrapolate the missing data. If you assume that the gradient changes smoothly it works like this:

In your x-gradient calculations you may have calculated the derivate A for pixel 1 and B for pixel 2. If you want to extrapolate a value for pixel 0 (the corner case) the value a-(b-a) could be used.

A numerical example:

```
pixel1: gradient = 100
pixel2: gradient = 80
extrapolate using a-(b-a):
pixel0: gradient = 100 - (80-100)) = 120
```

So, on one hand you want to keep it simple on the other hand you want your program to perform well. Huh.

I'm actually doing something similar, though, I don't care much about the border. I like to base the coefficients off of cubic B-Splines. If you convolve your discrete 2D signal with a 2D cubic B-Spline, you'll get a very smooth and twice continuously differentiable function. It's possible to compute the exact intensities and derivatives of this function at arbitrary points. Since the cubic B-Spline is not an interpolator the result will be a bit smoothed compared to the original. But that's not a problem for many applications. In fact, it tends to improve things (suppresing noise to some extent) in many situations. If you don't want this smoothing effect, you can get around it (see my reference below).

In one dimension, reconstruction using the cubic B-Spline as reconstruction filter followed by sampling the signal again is equivalent to convolving the signal with

```
1/6 4/6 1/6
```

The *exact* derivative of this is:

```
1/2 0 -1/2
```

And the *exact* second derivative is:

```
1 -2 1
```

These coefficients follow from the cubic B-Spline curve and its derivatives. In 2D you can combine this arbitratily. One filter for the x direction and one filter for the y direction. Examples:

```
"B-Spline reconstruction" (divisor=36)
1 4 1
4 16 4
1 4 1
"B-Spline differentiator in X" (divisor=12)
1 0 -1
4 0 -4
1 0 -1
"B-Spline, 2nd derivative in X, 1st derivative in Y" (divisor=2)
1 -2 1
0 0 0
-1 2 -1
```

The nice thing about this is, even though the filtered results don't correspond exactly to the original signal but only a slightly smoothed version, they are nontheless consistent with each other. You can get around the smoothing effect by using a simple preprocessing trick that is described here. You'll also But depending on what you actually want to do, this preprocessing might be inappropriate.

I use this to compute quadratic Taylor approximations at arbitrary (sub-pixel) points to find things like saddle points and local extremums.

If you care about the border you need to somehow choose an extrapolation that fits your needs. I typically just repeat the pixel values of the last pixels. It works well for *my* applications*.

How you deal with borders totally depends on the application. Mirroring, extrapolation, adding zeroes, depending on your needs it will do.

Now you take as border the brightness value, I would not do that, it has no meaning. Just act like your image has more pixels on all borders and mirror, extrapolate or zero their value for your derivative calculation.

Why not taking just a Sobel kernel? It is fast and not more coding effort?

Edit: you do not check the borders in x-direction. grad_x(0, 0) will result in a runtime exception.

OpenCV with the convolution kernel you used (`[1 0 -1]`

).

Depends on the application. Here are some nice ways to pad your image.

您可能感兴趣的文章：

- Facebook PHP SDK Birthday APP using FQL and HTML
- Finding the prime factor of a Long number using Java
- java - Finish input to array before printing all
- keeping css drop down menu item highlighted with php
- Mysql how to use COUNT value of rows from joined table in WHERE statement?
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?

随机阅读：

**推荐内容**-

**热点内容**-
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?
- git svn - git svn fetch does not fetch a Subversion commit message modified after initial clone
- java me - Why I am getting the bad length exception when I am running this application?
- java - How to get string.format to complain at compile time
- ruby on rails - Trigger observer of parent class on change
- python - Issue with URL pattern in Django with webmonkey tutorial