Prusa-Link icon indicating copy to clipboard operation
Prusa-Link copied to clipboard

Feature request: Flip/Rotate Pi camera image

Open mix579 opened this issue 2 years ago • 11 comments

The way the camera is mounted on my Mk3S printers, the picture from the Pi camera in PrusaLink is upside down. Would love to see an option in the Camera settings to flip it/rotate 180 degrees. I suspect it's possible to do that on the Pi somehow but I know nothing about it, and shouldn't have to.

mix579 avatar Apr 23 '23 19:04 mix579

I looked for it but did not find anything. In the end, I realized the new camera mount I wanted to print would solve the issue because it makes the camera's correct physical orientation. 😬

davidstosik avatar Apr 24 '23 10:04 davidstosik

I really want this too

cozmo14047 avatar Jun 09 '23 20:06 cozmo14047

It would be useful for me too

czesiu20 avatar Sep 25 '23 16:09 czesiu20

This is a must and should be fairly simple to implement. I tried to rotate raspberry camera v2 using /boot/config.txt with no luck...

kanzelsberger avatar Feb 11 '24 21:02 kanzelsberger

upvote, please add this

x23piracy avatar Feb 14 '24 00:02 x23piracy

It doesent look like this is going to be done. @TojikCZ

cozmo14047 avatar Feb 17 '24 08:02 cozmo14047

Yup, most likely not on PrusaLink side, sorry. Rotating a 4k photo in raw yuyv either needs a better programmer or a lot of power

TojikCZ avatar Feb 17 '24 09:02 TojikCZ

Well for those running PrusaLink on Raspberry Pi 3, 4 or 5 (probably also Zero 2) there is enough power. However, if that is complicated, why not do that on the frontend side? I would say it will be way too easy to do it in JavaScript when the image is received. It's one operation every 10 seconds in worst case, that is not very expensive.

kanzelsberger avatar Feb 17 '24 11:02 kanzelsberger

That's what i was thinking

TojikCZ avatar Feb 19 '24 09:02 TojikCZ

Aren't there ways, with Raspberry Pi and Camera, to rotate the image at the driver level?

Things I found googling:

  • alias raspivid="/usr/bin/raspivid -rot 90" (source)
  • v4l2-ctl --set-ctrl=rotate=90 (source)
  • Does libcamera.Transform apply at the driver level? (source)

There seem to be some options that are not "transpose the image data after taking the capture", though I'm not knowledgeable enough to confirm what you'd need in PrusaLink... 🤔


Another idea: EXIF data. 💡 When I rotate my iPhone (or digital camera) and take a picture, the file's data itself is not rotated so that the JPEG binary at the beginning of the file is the actual top left corner of my picture. Instead, an EXIF tag is added to the JPEG file:

exif orientation (source)

camera.exif:tags should allow the addition of the Orientation tag (doc)


I don't know how to edit the Python code directly on my Raspberry Pi Zero (I can SSH and found prusa-link, but it all seems to be compiled into .pyc files and my knowledge around that is basically none). Would something like this impact the output picture? (Having installed the exif package with eg. pip install exif.)

--- prusa/link/cameras/encoders.py  2024-02-26 11:44:40.581695756 +0900
+++ prusa/link/cameras/encoders.py 2024-02-26 11:34:40.280423311 +0900
@@ -15,6 +15,8 @@
 import numpy as np
 from turbojpeg import TJSAMP_422, TurboJPEG  # type: ignore

+from exif import Image as exifImage
+
 from . import v4l2

 jpeg = TurboJPEG()
@@ -357,6 +359,12 @@
             raise RuntimeError(
                 "Encoding failed - re-queueing the coded buffer")

+        image = exifImage(output)
+        image.set("Orientation", 3)
+        output = image.get_file()
+
         return output

I'd expect the image displayed in the PrusaLink web interface to be upside down.


Update: it works! Basically, removing encoders.pyc and copying encoders.py from the repository allowed me to run PrusaLink with the modified file (need to restart prusalink with prusalink restart). Of course, this is just a proof of concept and it would need more work (add a setting somewhere, store it, and use that setting instead of the hard-coded 3), but as a proof of concept, it shows that my Raspberry Pi Zero W was able to mark the image as rotated 180º using an EXIF tag (without having to transpose the whole binary data).

Here's the kind of image it showed in the UI:

image

Whereas without my hack, the image looks like this:

image

I can show the hack image's EXIF data in macOS' Preview app:

image

Orientation: 3 (Rotated 180º)


I also tried with "Orientation", 8 and it works too, though the web UI could use a scale fix. 😅 image

(Using width: 100% CSS leads to that.)

PrusaConnect looks rather nice too, though rotating the thumbnail retrieved from PrusaLink would require a bit more work. (It could be that PrusaConnect strips out EXIF info when generating a thumbnail of the image shared by PrusaLink.)

image

davidstosik avatar Feb 26 '24 00:02 davidstosik

Aren't there ways, with Raspberry Pi and Camera, to rotate the image at the driver level?

Things I found googling:

  • alias raspivid="/usr/bin/raspivid -rot 90" (source)

  • v4l2-ctl --set-ctrl=rotate=90 (source)

  • Does libcamera.Transform apply at the driver level? (source)

There seem to be some options that are not "transpose the image data after taking the capture", though I'm not knowledgeable enough to confirm what you'd need in PrusaLink... 🤔

Another idea: EXIF data. 💡 When I rotate my iPhone (or digital camera) and take a picture, the file's data itself is not rotated so that the JPEG binary at the beginning of the file is the actual top left corner of my picture. Instead, an EXIF tag is added to the JPEG file:

exif orientation (source)

camera.exif:tags should allow the addition of the Orientation tag (doc)

I don't know how to edit the Python code directly on my Raspberry Pi Zero (I can SSH and found prusa-link, but it all seems to be compiled into .pyc files and my knowledge around that is basically none). Would something like this impact the output picture? (Having installed the exif package with eg. pip install exif.)

--- prusa/link/cameras/encoders.py  2024-02-26 11:44:40.581695756 +0900
+++ prusa/link/cameras/encoders.py 2024-02-26 11:34:40.280423311 +0900
@@ -15,6 +15,8 @@
 import numpy as np
 from turbojpeg import TJSAMP_422, TurboJPEG  # type: ignore

+from exif import Image as exifImage
+
 from . import v4l2

 jpeg = TurboJPEG()
@@ -357,6 +359,12 @@
             raise RuntimeError(
                 "Encoding failed - re-queueing the coded buffer")

+        image = exifImage(output)
+        image.set("Orientation", 3)
+        output = image.get_file()
+
         return output

I'd expect the image displayed in the PrusaLink web interface to be upside down.

Update: it works! Basically, removing encoders.pyc and copying encoders.py from the repository allowed me to run PrusaLink with the modified file (need to restart prusalink with prusalink restart). Of course, this is just a proof of concept and it would need more work (add a setting somewhere, store it, and use that setting instead of the hard-coded 3), but as a proof of concept, it shows that my Raspberry Pi Zero W was able to mark the image as rotated 180º using an EXIF tag (without having to transpose the whole binary data).

Here's the kind of image it showed in the UI:

image Whereas without my hack, the image looks like this: image I can show the hack image's EXIF data in macOS' Preview app: image > Orientation: 3 (Rotated 180º)

I also tried with "Orientation", 8 and it works too, though the web UI could use a scale fix. 😅 image

(Using width: 100% CSS leads to that.)

PrusaConnect looks rather nice too, though rotating the thumbnail retrieved from PrusaLink would require a bit more work. (It could be that PrusaConnect strips out EXIF info when generating a thumbnail of the image shared by PrusaLink.)

image

Good job, you were actully able to do it ( somthing the devs couldnt do) @TojikCZ . I will be looking at doing this, maybe add a pull request

cozmo14047 avatar Feb 26 '24 07:02 cozmo14047