Thanks to visit codestin.com
Credit goes to github.com

Skip to content

vips_hough_line_vote ignoring votes for extreme values of rho and theta #4494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ecbypi opened this issue May 1, 2025 · 1 comment
Open
Labels

Comments

@ecbypi
Copy link

ecbypi commented May 1, 2025

Bug report

Please let me know if you need anything else.

Environment

  • OS: macOS Sequoia 15.4.1
  • Vips: 8.16.0 (installed via macports)
  • Ruby-vips: 2.2.3
  • Ruby: 3.4.2

Describe the bug
The calculations for r, ri, xd, and yd in vips_hough_line_vote appear to be incorrect, causing curves in the Hough image to be cut off for either low angles at high values of r or high angles at low values of r.

In a test script (below), I was able to address this by:

  1. Scaling and shifting ri to accommodate negative values
  2. Calculatingxd and yd by dividing x and y with the diagonal of the image instead of their respective image dimensions. This ensures r will stay within 1 and the adjusted ri within the bounds of height.

To Reproduce
I discovered this behavior with the following Ruby script. I was using it to clarify my understanding of how the width and height arguments to hough_line should be translated back to values of theta and rho.

What the script does:

  1. Create a 512 by 512 pixel black image with two pixels set to white.
  2. Create a Vips image from the nested array of pixel values; the image is output to a file for debugging
  3. Calculate the Hough space with Vips::Image#hough_line
  4. Calculate the Hough space manually using the changes mentioned under Describe the bug
  5. Output the Hough images and the images highlighting intersections in Hough images to files (examples attached below)
  6. Print intersections to stderr
#!/usr/bin/env ruby

# This script creates a 512x512 image with individual pixels set to white
#
# The `points` array is a list of points I was testing to see if they intersect
# in the output `hough_line`

require "ruby-vips"
require "pp"

# Check points at different orientations to each other
#
# Only rendering two points at at time for simplicity
points = [
  # Corner pixels to test boundaries
  #[1, 1],
  #[1, 512],
  #[512, 1],
  #[512, 512],

  # horizontal line
  #[128, 256],
  #[384, 256],

  # vertical line
  #[256, 128],
  #[256, 384],

  # Points where no intersection is found `Vips::Image#hough_line`
  # points that would produce theta > 135; no intersection is found
  #[118, 128],
  #[274, 384],

  # Pixels at the right edge of the image that would cause theta to be near 180
  [511, 1],
  [512, 512],
]


# Build the image as an array of zeros
image_array = [[0]] * 512
image_array = [image_array] * 512

# Change the points to 255 (white)
points.each do |(x, y)|
  row_index = x - 1
  column_index = y - 1

  row = image_array[column_index].dup
  row[row_index] = [255]
  image_array[column_index] = row
end

image = Vips::Image.new_from_array(image_array)
image.write_to_file("test-hough-source.jpeg")

# Using a large number of theta steps to ensure pixels overlap in the Hough
# space overlap
theta_segments = 1800
# Using dimensions of the image times 2 to make sure I understand what the
# values of rho mean in the output of `hough_line`
rho_segments = 1024

#
## VIPS CALCULATION
#
hough_image = image.hough_line(width: theta_segments, height: rho_segments)

#
## MANUAL CALCULATION
#
# Manually find the Hough space for the image using an updated calculation for
# rho
hough_space_array = []
rho_segments.times do
  hough_space_array << [0] * theta_segments
end

sine_values = (0...theta_segments * 2).map { Math.sin(2 * Math::PI * _1 / (2 * theta_segments)) }

# Store this as a variable for debugging the calculation of `rho_step`
_points_sinusoids = points.map do |x, y|
  # This part of the calculation in `vips_hough_line_vote` needs to be updated
  # too
  x_normalized = x / Math.sqrt(2 * 512 ** 2)
  y_normalized = y / Math.sqrt(2 * 512 ** 2)

  (0...theta_segments).map do |theta_step|
    rho_normalized = x_normalized * sine_values[theta_step + theta_segments / 2] + y_normalized * sine_values[theta_step]

    # Compact and shift `rho_step` to fit in `rho_segments`
    #
    # For theta 0 - 180, the lower 15% of `rho_segments` will never have a value
    #
    # Calculating the Hough space for 0 - 360 would populate these values
    rho_step = (rho_normalized * rho_segments).to_i / 2 + (rho_segments / 2)

    hough_space_array[rho_step][theta_step] += 1

    rho_step
  end
end

hough_space_buffer = "".encode("BINARY")
hough_space_array.each do |row|
  hough_space_buffer << row.pack("C*")
end

hough_adjusted_image = Vips::Image.new_from_memory(hough_space_buffer, theta_segments, rho_segments, 1, "uchar")

[["default", hough_image], ["adjusted", hough_adjusted_image]].each do |name, image|
  image_any_votes = image > 0
  image_any_votes.write_to_file("test-hough-pixels-#{name}.jpeg")

  image_intersections = image > 1
  image_intersections.write_to_file("test-hough-intersections-#{name}.jpeg")

  # Outputting 5 values because the high resolution for theta means there can be
  # more than one intersection in Hough space for one line
  $stderr.puts "#{name}:"
  $stderr.puts image_intersections.max(size: 5, x_array: true, y_array: true, out_array: true).inspect
end

Expected behavior
Curves in Hough space should not be cut off.

Actual behavior
Curves in Hough spaces are cut off around 45 and 135 degrees.

Screenshots

Pixels at (118, 128) and (274, 384) creating a line with theta = 148
Vips::Image#hough_line
Image

Manual calculation
Image

Pixels at (511, 1) and (512, 512) creating a line with theta near 180; demonstrates curves being cut off at low angles
Vips::Image#hough_line
Image

Manual calculation
Image

🙏🏼Thanks for reading.

@ecbypi ecbypi added the bug label May 1, 2025
@jcupitt
Copy link
Member

jcupitt commented May 1, 2025

Hi @ecbypi, thanks for the bug report! I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants