-
Notifications
You must be signed in to change notification settings - Fork 27
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
Rotate and resize photo before saving #2015
Conversation
dd6d004
to
94fcb55
Compare
try: | ||
for orientation in ExifTags.TAGS.keys(): | ||
if ExifTags.TAGS[orientation] == "Orientation": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than a try
/except
here, might an if
/else
be clearer:
if "Orientation" in ExifTags.TAGS.keys():
# Do exif orientation tag rotation
else:
# Do `Roll` based rotation
# Do saving the image
At the moment you don't save the image if you do the exif approach, because it's within the Except
block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done as suggested replacing the try/except
with if/else
for clarity, but the for
loop is still necessary.
# if roll is positive, then the image needs to be rotated 90 degrees clockwise | ||
if detected["FaceDetails"][0]["Pose"]["Roll"] > 0: | ||
print("Rotate 90 degrees clockwise") | ||
rotated = image.rotate(angle=90) | ||
rotated.show() | ||
# if roll is negative, then the image needs to be rotated 90 degrees counter clockwise | ||
elif detected["FaceDetails"][0]["Pose"]["Roll"] < 0: | ||
print("Rotate 90 degrees counter clockwise") | ||
rotated = image.rotate(angle=270) | ||
rotated.show() | ||
# if roll is 180, then the image is upside down | ||
elif detected["FaceDetails"][0]["Pose"]["Roll"] == 180: | ||
print("Upside down") | ||
rotated = image.rotate(angle=180) | ||
image.show() | ||
# if roll is 0, then the image is upright | ||
else: | ||
print("Roll is:", detected["FaceDetails"][0]["Pose"]["Roll"]) | ||
print("No rotation needed") | ||
pass | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this approach will do what you want. Splitting the images into categories roll < 0
, roll > 0
and roll == 180
isn't going to work. For one thing, the roll ==180
criteria will never be hit. There's also the issue that when roll == -165
you probably still want to rotate the image by 180° rather than 165°.
Instead I think what you want to do is : "Calculate the angle image is rotated by rounding the roll value to the nearest multiple of 90". Some examples:
-178 -> -180
75 -> 90
-12 -> 0
etc.
You can do this as: img_rotation_angle = 90 * round(roll / 90)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Hadn't gotten that far yet, but this is useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved with 25833f9
5ab256a
to
2b6b956
Compare
8a652c4
to
c4d8a32
Compare
@@ -70,6 +71,7 @@ <h1>Uploaded photos for review</h1> | |||
<td>{{ queued_image.election_date }}</td> | |||
<td>{% if queued_image.user %}{{ queued_image.user.username }}{% else %}a robot 🤖{% endif %}</td> | |||
<td><a href="{% url 'person-view' person_id=queued_image.person.id %}">{{ queued_image.person.id }}</a></td> | |||
<td>{% if queued_image.detection_metadata %}Photo Angle: {{ queued_image.photo_angle }}{% else %}Image analysis is not available for this photo.{% endif %}</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this as a placeholder, but what would be useful to display here? Do we want to display the entire (collapsible)dict
or ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved in 8d93e51
c2d961c
to
c4d8a32
Compare
My image is being autorotated when I view it in the moderation queue, but when I run the mgmt command I'm getting the following: Wondering if I've missed a config step or something? |
Yes, my fault - I forgot to mention you need current AWS creds to run the command. Will add that step above. |
We're seeing a lot more larger images (mainly as phone cameras get better), so I wonder if we should resize the image to be no larger than, say, a 5MB PNG on upload? And then we'll get better results from rekognition too. |
89507fd
to
dbbcb43
Compare
Done with dbbcb43 |
I've just tried this out with a photo from my phone camera - getting this back from the mgmt command
File size according to my OS: 1,138,636 bytes (1.1 MB on disk) Also tried it with the example image from the previous commit but I'm getting a weird error there. Not sure what would cause that but I suppose that could be a me problem.
^ full trace on this one via Slack so I don't bulk up the comments here too much |
571cfb4
to
8b1137c
Compare
I've refactored the helpers to handle the correct file types at each of the rotate, resize, convert steps in the save process. 8b1137c |
Seeing some odd behaviour now. The example photo is now being rotated clockwise (even though the photo being uploaded is already oriented correctly) but I am able to run facial recognition on it now. The selfie I've been testing with is still not able to do facial recognition, but I don't know how much of a problem that is. |
- This commit also fixes a bug with resizing images
I see this too on some photos (not my selfie). On further inspection, these cases do not appear to go through the rotation step at all. It would be good to look at this together. |
8b1137c
to
28a59cb
Compare
UPDATE: I dug deep back into the rotate images bug and made some changes. The behaviour @Bekabyx Bek found confirmed that my assumptions about photos with an orientation set to |
I've given this another run through with just a normal photo and everything still seems to be working so I'm happy to approve. We can always revisit again if we want it to be all-singing-all-dancing, but with the manual rotate functionality I think it's okay to leave it at this at least for now 😁 |
Ref python-pillow/Pillow#4703 and https://trello.com/c/gEpWTwI9/3323-photo-rotation
The problem: https://candidates.democracyclub.org.uk/moderation/photo/review
In this PR:
convert_to_png
function to account for two diff types of incoming image files. Rotating images at this point prevents the issue in the mod queue - in many but not all cases. In those cases, there is still the ability to manually rotate in the queue.To test the changes to uploading an XL, rotated photo: As a superuser, upload a photo that is larger than 5MB and needs rotation to a person on a locked (or suggested lock) ballot. Do not use a photo from the current mod queue as that won't have exif data (message me if you need a photo with exif data or possibly use a phone selfie). Navigate to the mod queue. The photo should appear correctly rotated before review.
Make sure your AWS credentials are current. Run the detect faces management command to store
detection_metadata
on thequeued_image
. Run the server again and navigate to the review page; below the image and rotation buttons, check the message or detection data is rendered.New Recording - 4/26/2023, 11:48:41 AM
Tasks