# plate orientation based on shape

**URL:** <https://forums.openmv.io/t/plate-orientation-based-on-shape/11893>\
**Category:** Kickstarter Topics\
**Created:** [September 28, 2026, 6:01pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893 "2026-09-28T18:01:46Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 6:01pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/1 "2026-09-28T18:01:46Z")

</div>

Hi.  
I’m new to this field, and I wanted to ask some questions to help my colleagues at work.  
I wanted to use an OpenMV camera to orient plates arriving on a conveyor belt in random positions; a mechanical orienter rotates them, and we use a photocell to try to adjust the plate’s orientation.  
My idea was to use a camera to read the angle or shape of the plate so that it places the plate in the correct position.  
Before investing any money, I wanted to know if this is possible using OpenMV cameras. Thanks, and sorry for my English.

 ![3b8a1ebb-5ef3-4c86-bde0-14fab3dca2fa](https://canada1.discourse-cdn.com/flex029/uploads/openmv1/original/2X/e/ea01b960addfbf2d0395120898b24759ade40dd1.jpeg)

---

<div class="post-metadata">

**Author:** ![kwagyeman](https://yyz1.discourse-cdn.com/flex029/user_avatar/forums.openmv.io/kwagyeman/32/4_2.png) [@kwagyeman](https://forums.openmv.io/u/kwagyeman)\
**Post date:** [September 28, 2026, 6:02pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/2 "2026-09-28T18:02:58Z")

</div>

Hi, it is. Can you provide a view from what the camera would likely see so I can suggest an alogirithm?

---

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 6:36pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/3 "2026-09-28T18:36:29Z")

</div>

![20260928_202645](https://canada1.discourse-cdn.com/flex029/uploads/openmv1/original/2X/7/764a679c3a36a5c24e7a28344f63d50f3e65fe3f.jpeg)

 ![20260928_202925](https://canada1.discourse-cdn.com/flex029/uploads/openmv1/original/2X/4/40b38752a70614f7bc44d23c5a0b0095dab7cf31.jpeg)

 ![20260928_203000](https://canada1.discourse-cdn.com/flex029/uploads/openmv1/original/2X/6/69a7705162450fa6959308a3e028f05c2f60875f.jpeg)

For this project, I was thinking of using an H7; this decision was made in consultation with the AI.😂

---

<div class="post-metadata">

**Author:** ![kwagyeman](https://yyz1.discourse-cdn.com/flex029/user_avatar/forums.openmv.io/kwagyeman/32/4_2.png) [@kwagyeman](https://forums.openmv.io/u/kwagyeman)\
**Post date:** [September 28, 2026, 6:52pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/4 "2026-09-28T18:52:43Z")

</div>

Thanks, but, it’s not clear what you are trying to rotate? The plate is round and the same on all sides? So, what needs rotation?

---

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 7:10pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/5 "2026-09-28T19:10:51Z")

</div>

The plates are not identical: one is oval and the other is triangular. I would like to position the oval one with its longest side facing the conveyor belt, and the triangular one with its tip pointing towards the camera. I am attaching two photos showing examples of the plates I use.

 ![20260928_210543](https://canada1.discourse-cdn.com/flex029/uploads/openmv1/original/2X/2/234ccdfa01776874108ca8f57dc4f5e76d44ca8b.jpeg)

---

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 7:32pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/6 "2026-09-28T19:32:22Z")

</div>

The way we orient the plates right now isn’t very reliable; it often makes mistakes because it detects the white too early.

[Video](https://streamable.com/un8fl1)

---

<div class="post-metadata">

**Author:** ![kwagyeman](https://yyz1.discourse-cdn.com/flex029/user_avatar/forums.openmv.io/kwagyeman/32/4_2.png) [@kwagyeman](https://forums.openmv.io/u/kwagyeman)\
**Post date:** [September 28, 2026, 7:37pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/7 "2026-09-28T19:37:20Z")

</div>

Mmm, this is solvable but challenging.

You can use an image classifier trained via ML, or structure via blob detection.

…

Hmmm, so, using an AI coder here is likely to have good results. What you’ll want to do is apply strong image binarization, then extract the contour of the plate edge. From that, you can fit a curve to the contour points. The curve variables can then be bucketed, and this will tell you which plate you have and its rotation, which can be seen uniquely.

Normally, the above… would be generally a pain to write, but, if you feed that into an AI and tell it to use our numpy ULAB package onboard it can more or less solve it.

Once you have the program, you’ll need to collect the curve info for the plates to get the profiles to compare against, but after you have that data, the AI will be able to make something that’s pretty robust for matching.

The resulting Python code it will write, though, is going to be some very complex curve-fitting functions and heavy mathematics.

---

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 7:43pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/8 "2026-09-28T19:43:13Z")

</div>

I used Gemini to arrive at this solution. It recommends using an OpenMV H7 and inserting this Python code.

````python
import sensor, image, time, pyb, math

# 1. Inizializzazione della Telecamera
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE) # Bianco e nero per massima velocità
sensor.set_framesize(sensor.QVGA) # Risoluzione 320x240
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # Disattiva regolazioni automatiche per stabilità
sensor.set_auto_whitebal(False)

# 2. Configurazione Pin di Uscita verso il Relè (Pin P0)
relay_pin = pyb.Pin("P0", pyb.Pin.OUT_PP)
relay_pin.low()

# 3. Parametri di Configurazione (Da ritoccare se necessario)
THRESHOLD = (180, 255) # Soglia luminosità per staccare il piatto bianco dallo sfondo
ANGOLO_OVALE = 90 # Gradi target per il piatto Ovale quando è dritto
ANGOLO_TRIANGOLO = 45 # Gradi target per il piatto Triangolare quando è dritto
TOLLERANZA = 3 # Margine di errore in gradi (+/-)

clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()

    # Rileva le forme chiare nell'inquadratura (i piatti)
    blobs = img.find_blobs([THRESHOLD], pixels_threshold=3000, area_threshold=3000, merge=True)

    piatto_allineato = False

    if blobs:
        # Prendi l'oggetto più grande presente sul nastro
        piatto = max(blobs, key=lambda b: b.pixels())

        # Disegna il riquadro e il centro a schermo per verifica visiva nell'IDE
        img.draw_rectangle(piatto.rect(), color=255)
        img.draw_cross(piatto.cx(), piatto.cy(), color=255)

        # Calcola l'angolo dell'asse (convertito in gradi 0-180)
        angolo_rilevato = int(math.degrees(piatto.rotation())) % 180
        
        # Rapporto tra larghezza e altezza del riquadro per distinguere i 2 piatti
        rapporto_lati = piatto.w() / float(piatto.h())

        # Distinzione automatica tra Ovale e Triangolo
        if rapporto_lati > 1.15 or rapporto_lati < 0.85:
            # Sagoma allungata -> Piatto OVALE
            angolo_target = ANGOLO_OVALE
            img.draw_string(10, 10, "OVALE", color=255, scale=2)
        else:
            # Sagoma più proporzionata -> Piatto TRIANGOLARE
            angolo_target = ANGOLO_TRIANGOLO
            img.draw_string(10, 10, "TRIANGOLO", color=255, scale=2)

        # Verifica se l'angolo rientra nella tolleranza
        if abs(angolo_rilevato - angolo_target) <= TOLLERANZA:
            piatto_allineato = True

    # 4. Comando al Relè verso l'ingresso I3 del Siemens LOGO!
    if piatto_allineato:
        relay_pin.high() # Chiude il relè -> invia 24V al PLC
        img.draw_string(10, 200, "STOP (ALLINEATO)", color=255, scale=2)
    else:
        relay_pin.low() # Mantiene il relè aperto```
````

---

<div class="post-metadata">

**Author:** ![kwagyeman](https://yyz1.discourse-cdn.com/flex029/user_avatar/forums.openmv.io/kwagyeman/32/4_2.png) [@kwagyeman](https://forums.openmv.io/u/kwagyeman)\
**Post date:** [September 28, 2026, 8:01pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/9 "2026-09-28T20:01:01Z")

</div>

Please surround your code pastes with code tags. As for what it’s doing, that approach is too simplistic. As you cannot see the whole plate at once it won’t work. The approach I outlines will work given only seeing a partial plate.

Either way, if you just let the AI iterate on the code it will find a solution. We’ll have a version of OpenMV IDE out soon which will be able connect to an auto coder and allow it to program the camera automatically in a month or so.

---

<div class="post-metadata">

**Author:** ![pakoscosta](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@pakoscosta](https://forums.openmv.io/u/pakoscosta)\
**Post date:** [September 28, 2026, 8:40pm UTC](https://forums.openmv.io/t/plate-orientation-based-on-shape/11893/10 "2026-09-28T20:40:11Z")

</div>

Sorry about the code. I’ll log in from my PC tomorrow and fix it. I’ll wait for the new version of the IDE and start running some tests with photos.
