Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Detecting whether a portrait image is upsidedown or in wrong orientation #365

Unanswered
mur-wtag asked this question in Q&A
Discussion options

We have using ruby-vips for a long time and it's amazing. Lately, we have found some images are uploaded in flipped or not in right orientation! We tough .autorot will resolve this issue but it's not.

So, I've been trying to detect human face (as our system instruct user to upload portrait image of themselves). For that I'm using hough_circle to detect largest circle in the image (human face as circle).

I've reuse your code you suggested here #276 (comment) and with help of that I've found largest circle in the image. Note: I've searched for circle which is quarter of the image and getting x, y coordinate of the center :

radius_target = [image.width, image.height].min / 4

with help of the center I've been using this logic to determine the degree to rotate:

if y > (image.height / 2)
 0
elsif x < (image.width / 2) && y < (image.height / 2)
 90
elsif x > (image.width / 2) && y < (image.height / 2)
 -90
else
 180 # upside down
end

with this it seems like it's not working in most of the cases. So, could you guys help me to resolve this issue? It would be really it will be really appreciated!

Thanks!

You must be logged in to vote

Replies: 1 comment 1 reply

Comment options

Hi @mur-wtag,

Sorry, I'm very busy right now, I probably won't be able to look at this until July.

Some sample images and complete, runnable code would be useful.

You must be logged in to vote
1 reply
Comment options

Oh sure! at anytime if we could resolve it, is great!

here is the sample images: https://drive.google.com/drive/folders/1-WQNKMOP98eNyfrIy_hCJPq-AjBcbcNs?usp=sharing

And code is actually yours one, I've just modified a bit to determine the degree:

#!/usr/bin/ruby
require 'vips'
image = Vips::Image.new_from_file(ARGV[0])
# we need a one-band image of just the edges for circle detection
edges = image.colourspace(:b_w).flatten.canny(precision: :integer)
# search for circles roughly the size of the image, so radius of half the
# diameter of the largest circle
radius_target = [image.width, image.height].min / 4
radius_margin = 20
detect = edges.hough_circle(min_radius: radius_target - radius_margin,
 max_radius: radius_target + radius_margin)
# look for the (x, y) with the peak, then at that point, find the radius
strength, opts = detect.max(x: true, y: true)
x = opts["x"]
y = opts["y"]
bands = detect.getpoint(x, y)
radius_detected = bands.each_with_index.max[1] + radius_target - radius_margin
degree_to_rotate = if y > (image.height / 2)
 0
 elsif x < (image.width / 2) && y < (image.height / 2)
 90
 elsif x > (image.width / 2) && y < (image.height / 2)
 -90
 else
 180
 end
puts "strength = #{strength}, x = #{x}, y = #{y}, radius = #{radius_detected}, degree = #{degree_to_rotate}, W = #{image.width}, H = #{image.height}"

And output is:

for proper image:

ruby ./detect_circle.rb ~/img.jpg
# strength = 161.0, x = 150, y = 177, radius = 59, degree = 90, W = 307, H = 386
# should be degree = 0

for the image which need be rotated in 90 degree:

ruby ./detect_circle.rb ~/img2.jpg
#strength = 158.0, x = 114, y = 158, radius = 85, degree = 0, W = 386, H = 307
# should be degree = 90

If we could determine the rotating degree we can use this code to make the image in proper orientation:

 ImageProcessing::Vips.source(file).rotate(degree, background: [255, 255, 255]).call

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /