Help for HORIZON
PURPOSE:
HORIZON detects strong and weak horizon borders for martian images.
The program currently supports only grayscale format. The input images
to the program must be a 1-band image. The program makes two assumptions
for input images. If input images don't fullfil the assumptions, the
program will fail to detect horizon borders. The first assumption is
that sky region is above ground region. The second assumption is that
there is no object in sky region.
The output of this program will be a Comma-separated values (CSV) file.
The length of the output CSV file should always be exactly the the same as
input image's width. Each integer value in the CSV file represents the
horizon border's LINE position in that specific SAMP.
For example:
324,325,-1,325,326,327, ... ...
This means that at column(SAMP) 0, the horizon border is at row(LINE) 324;
at column(SAMP) 1, the horizon border is at row(LINE) 325. At column(SAMP) 2,
the horizon border value is -1, it means there is no horizon border detected
or it is an outlier.
EXECUTION:
The program is quite sensitive to the parameters. Parameters' default values
are chosen experimentally. In the METHOD section, the algorithm used in this
program is introduced. Knowing exactly how the algorithm works will help
choose parameters' values.
1) HORIZON INP=input.img OUT=output.horizon
Use all default parameters' values, the program takes an input image, and then
generate a CSV file that contains the horizon borders.
2) HORIZON INP=input.img OUT=output.horizon WH_ITER_MAX=0
By setting parameter WH_ITER_MAX to be 0, the program will turn off weak horizon
detection and refinement process. This is useful when salt-and-pepper noise was
not completely removed from preprocessing, and it is also useful when vignetting
effects present in the input image.
3) HORIZON INP=input.img OUT=output.horizon FILTER_SIZE=9
By default the program uses a filter window size of 7 to blend salt-and-pepper
noise. This should work for most of cases. However, if a lot of noisy pixel
appear in a given N x N space, then increase FILTER_SIZE should be helpful to
blend these noisy pixels to a degree which they don't affect the sky and ground
busyness levels calculation.
4) HORIZON INP=input.img OUT=output.horizon SH_THRESH_MAX=700
The parameter SH_THRESH_MAX defines the upper searching bound for gradient
magnitude image in preliminary horizon borders detection process. By decreasing
SH_THRESH_MAX value, the program will search more precisely for weaker horizon
borders. This parameter is useful when strong horizon borders appear to be weaker
than normal, or in another words, the sky pixels intensity is very close to ground
pixels intensity.
5) HORIZON INP=input.img OUT=output.horizon BAR_THRESH=5 BAA_THRESH=10
The parameters BAR_THRESH and BAA_THRESH are used to identify and remove columns
without sky region. If part of detected horizon borders are too close to the top
of image, then these horizon borders will be directly marked as false horizon,
and the value of these horizon borders will be set to -1. (Note: based on
the algorithm in this program, the false horizon borders will always be very
close to the top of image, and will appear to be a zigzag pattern.) The parameter
BAR_THRESH and BAA_THRESH are useful when horizon borders occupy only part of the
image.
METHOD:
The horizon detection algorithm consists of the following steps:
1) Trim top, bottom, left, and right borders of the input image.
2) Use a min, or max, or median filter with filter window size defined by
FILTER_SIZE parameter to smooth out salt-and-pepper noise in input images.
3) Use Sobel operator to compute gradient magnitude image and gradient
direction image based on the smoothed image.
4) Preliminary horizon borders detection by optimizing the difference of sky
and ground busyness levels. Horizon borders are a 1 dimensional array that
has the same width as the original input image.
5) Outliers and weak horizon borders detection and refinement.
6) Remove the outliers that cannot be refined from pervious step. Remove the
columns without sky region.
Depending on input image types, sometimes there are one or two lines appear on
top, bottom, left, or right of input images that are significantly brighter or
darker than their neighboring pixels. If these lines are not trimmed, it will
result in very strong edges when calculating gradient magnitude images. These
strong edges contribute to sky and ground busyness level calculation, and the
accuracy of detecting horizon borders decrease significantly.
Salt-and-pepper noise presents itself as sparsely occurring white and black pixels.
Median filter should be effective to remove salt-and-pepper noise; max filter should
be effective to remove pepper noise; min filter should be effective to remove salt
noise. Filter window size is crucial when removing noise, and it is usually an odd
number. In general, the larger the filter window size, the more blurry the resulted
image is.
Sobel operator has one 3x3 horizontal kernel and one 3x3 vertial kernel.
horizontal kernel: | -1 0 1 | vertial kernel: | -1 -2 -1 |
| -2 0 2 | | 0 0 0 |
| -1 0 1 | | 1 2 1 |
Convolve horizontal kernel with the original image will give us the edges horizontally
denoted as Gx, and convolve vertial kernel with the original image will give us the
edges vertically denoted as Gy. Based on the properties of the two kernels, Gx is
defined as increasing in the "right" direction, and Gy is defined as increasing in the
"down" direction. Combine Gx and Gy use the equation listed below will give us gradient
magnitude image and gradient direction image.
1. G = sqrt(Gx^2 + Gy^2) gradient magnitude image.
2. theta = arctan(Gy / Gx) gradient direction image, depending on whether Gx and Gy
are positive or negative numbers, theta belongs to different
quadrants.
The preliminary horizon borders are calculated by maximizing the difference of sky and
ground busyness levels. The optimization function Jn is defined below:
Jn = Ground_busyness_level - Sky_busyness_level (1)
which
sum(ground pixels from gradient magnitude image)
Ground_busyness_level = -------------------------------------------------- (2)
count(ground pixels from gradient magnitude image)
sum(sky pixels from gradient magnitude image)
Sky_busyness_level = ----------------------------------------------- (3)
count(sky pixels from gradient magnitude image)
The complete algorithm of finding maximum Jn value Jn_max is defined below:
thresh_max - thresh_min
n = ------------------------- + 1
search_increment_factor
for k = 1 to n
thresh_max - thresh_min
t = thresh_min + ----------------------- x (k - 1)
n - 1
for samp = 0 to image_width
border_tmp[samp] = image_height
for line = 0 to image_height
if gradient_magnitude_image(line, samp) >= t
border_tmp[samp] = line
break
end if
end for
end for
compute Ground_busyness_level using equation (2) listed above
compute Sky_busyness_level using equation (3) listed above
Jn = Ground_busyness_level - Sky_busyness_level
if Jn > Jn_max
Jn_max = Jn
border = border_tmp
end if
end for
Outliers and weak horizon borders detection and refinement is an iterative process.
The maximum iteration of detection and refinement is determined by either WH_ITER_MAX
parameter or if there is no outlier and weak horizon detected. A horizon column is
defined as outlier if its value is bigger or smaller than the average of its N neighbors
by a threshold value. Determine whether a horizon column has weak horizon above it
depends on two inputs from gradient magnitude image and gradient direction image. First,
in gradient magnitude image, if there is a pixel value that is bigger or smaller than
the average of all pixle values above the current detected position by a threshold value,
then the program will further check gradient direction image. In gradient direction image,
if a NxN space with the suspicious weak horizon pixel at the center contains more than 1/3
pixels that are almost equal to the suspicious weak horizon pixel, then the suspicious weak
horizon pixel will be defined as weak horizon pixel. The reason to use both gradient
magnitude image and gradient direction image is to increase the accuracy of weak horizon
detection. If only gradient magnitude image is used, the weak horizon detected can highly
be a salt-and-pepper noise that was not successfully removed from preprocessing step.
Once the horizon columns are marked as outlier or weak horizon existence, the optimizing
difference of sky and ground busyness levels algorithm introduced above will be performed
on these columns individually.
In order to remove columns without sky region, the program must be able to first detect
them. The program analyzes the shape of the detected horizon borders to determine which
part is true horizon and which part is columns without sky region. The false horizon borders
detected for the columns without sky region will satisfy the following two conditions:
1) very close to the top of the image.
2) the shape of the horizon borders appears to be in a "zigzag" pattern.
For testing condition 1, the average of horizon border is calculated, and parameters BAA_THRESH
and BAR_THRESH threshold values are defined. For testing condition 2, the average of the absolute
difference of horizon border is calculated, and parameters BAADA_THRESH and BAADR_THRESH threshold
valeus are defined. BAA_THRESH stands for border average accept threshold; BAR_THRESH stands for
border average reject threshold; BAADA_THRESH stands for border average of absolute difference
accept threshold; BAADR_THRESH stands for border average of absolute difference reject threshold.
The algorithm of determining true and false horizon is shown below:
compute border_avg
compute border_avg_absdiff
if border_avg <= BAR_THRESH ||
(border_avg <= BAA_THRESH && border_avg_absdiff >= BAADA_THRESH) ||
border_avg_absdiff >= BAADR_THRESH
marked as outliers or columns without sky region
else if border_avg > BAA_THRESH && border_avg_absdiff < BAADA_THRESH
marked as true horizon
else
break the horizon borders in half, and recursively call this
algorithm until all the horizon borders are categorized.
end if
HISTORY:
2016-04-05 Steven Lu Initial horizon by Steven Lu.
COGNIZANT PROGRAMMER: Steven Lu
PARAMETERS:
INP
A single 1-band grayscale input image.
OUT
A Comma-separated values (CSV) file.
SH_THRESH_MIN
Minimum threshold value for detecting strong horizon borders.
SH_THRESH_MAX
Maximum threshold value for detection strong horizon borders.
SH_SIF
Strong horizon search incremental factor.
WH_THRESH_MIN
Minimum threshold value for detecting weak horizon borders.
WH_THRESH_MAX
Maximum threshold value for detecting weak horizon borders.
WH_SIF
Weak horizon search incremental factor.
OUTLIER_THRESH
If the position a horizon border is vertically away its N immediate neighbors
by the value of this parameter in pixels, the horizon border will be classified
as an outlier.
OUTLIER_SIF
Outlier search interval factor.
WH_MAG_THRESH
Gradient magnitude image weak horizon borders threshold value.
WH_DIR_THRESH
Gradient direction image weak horizon borders threshold value.
WH_DIR_SIF
Gradient direction image weak horizon searching interval factor.
WH_ITER_MAX
Maximum iterations to search for weak horizon borders.
BAA_THRESH
Border average acceptance threshold value.
BAR_THRESH
Border average rejection threshold value.
BP_FACTOR
Border partition factor.
BAADA_THRESH
Border average of absolute difference acceptance threshold value.
BAADR_THRESH
Border average of absolute difference rejection threshold value.
SMOOTH_IMG
Optional output for smoothed image.
GM_IMG
Optional output for gradient magnitude image.
GD_IMG
Optional output for gradient direction image.
QL_IMG
Optional output for horizon borders overlay on top of the original
image served for quick look purpose.
FILTER_SIZE
The smoothing filter size in pixels.
FILTER_TYPE
The smoothing filter type.
TRIMTOP
Number of line(s) to cut from the upper border of the input image.
TRIMBOT
Number of line(s) to cut from the lower border of the input image.
TRIMLEFT
Number of sample(s) to cut from the left border of the input image.
TRIMRIGHT
Number of sample(s) to cut from the right border of the input image.
TRIM_IMG
Optional output for image with borders trimmed.
See Examples:
Cognizant Programmer: