-
Notifications
You must be signed in to change notification settings - Fork 62
-
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!
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 1 reply
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
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!
Beta Was this translation helpful? Give feedback.