Skip navigation

Új képmátrix létrehozása és rajzolás

Numpy mátrix létrehozása

Az előző példaprogramokban a képeket külső képfájlokból olvastuk be, aminek a reprezentációja egy Numpy tömb. Természetesen saját új mátrixokat is létrehozhatunk, és képmátrixként használhatunk.

Első lépésként szükséges a Numpy csomag importálása a programunkba. Az as kulcsszó után megadott np néven új aliast adunk, hogy kevesebbet kelljen gépelni a csomag nevét.

import numpy as np

A Numpy ndarray() függvényével hozható létre új, n-dimenziós mátrix, aminek az elemtípusát is meg kell adnunk. Például egy 200 sorból, 320 oszlopból álló, előjel nélküli 8 bites egész értékekkel reprezentált 3 csatornás kép létrehozása az alábbi:

img = np.ndarray((200, 320, 3), np.uint8)

A mátrix dimenzióit Python felsorolási tuple típusként kell átadni, ami zárójelek között, vesszőkkel elválasztott értékeket jelent. Fontos, hogy ez egy darab paraméter objektumként értelmeződik, vagyis a fenti függvényhívás 2 paramétert kap meg. A típusokkal később foglalkozunk.

Innentől az img változó tartalma egy Numpy objektum lesz, amelynek elérhetjük az attribútumait és függvényeit. Pl. a fill() segítségével minden csatorna minden eleme a függvényparaméter értékét kapja.

OpenCV rajzoló függvények

Az OpenCV lehetőséget biztosít képmátrixba egyszerű raszteres grafikus elemek, mint például kör, vonal, szöveg elhelyezésére.

Példa kör rajzolásra

cv2.circle(img, (50, 100), 40, (0, 0, 192), -1)

Ez az img képmátrixban helyez el kört (50, 100) középponttal, 40 pixel sugárral, 192 fényességértékű vörös színnel, alapértelmezett vonalvastagsággal, negatív érték esetén kitöltött belső területtel (pozitív értékkel csak a körvonalat rajzolja).

Fontos! Az OpenCV a koordinátákat (oszlop, sor) sorrendben értelmezi, ellentétben a Numpy konvencióval! Mindig figyeljünk arra, hogy Numpy tömbelérést, vagy OpenCV függvényhívást végzünk a koordináták megadásakor!

Emlékeztetőül: A paraméterlistában kerek zárójelek között megadott értékek egy darab, felsorolási (tuple) paraméterértéknek értelmeződnek!

A szín tuple érték helyett skalár számértéket is megadhatunk, például szürkeárnyalatos képmátrixba rajzolva célszerű is ilyet használni.

A vonalvastagság képpontban értendő. Negatív érték esetén kitöltött belső területtel rajzol, pozitív értékkel csak a körvonal jelenik meg.

Vonal

cv2.line(img, (kezdo_x, kezdo_y), (veg_x, veg_y), (b, g, r), vastagsag)

Téglalap

cv2.rectangle(img, (bal_felso_x, bal_felso_y), (jobb_also_x, jobb_also_y), (b, g, r), vastagsag)

Ellipszis

cv2.ellipse(img, (kozep_x, kozep_y), (fotengely_hossz, mellektengely_hossz),
fotengely_szog, kezdoszog, zaroszog, (b, g, r), vastagsag)

A főtengely szögének kezdőállása az X-tengely iránya. A pozitív körüljárási irány az óramutató járásával ellentétes. Az értékek fokban értelmeződnek.

A kezdőszög és zárószög megadásával elliptikus ívet rajzolhatunk.

Sokszög körvonalak és kitöltött sokszögek

cv2.fillPoly(img, pts, szín[, vastagság])
cv2.polylines(img, pts, isClosed, szín[, vastagság])

A könyebb érthetőség kedvéért egy konkrét példát is megadunk:

contour1 = np.array([[130, 20], [150, 150], [250, 150], [280, 50]])
cv2.fillPoly(img, [contour1], color=(0, 192, 0))
cv2.polylines(img, [contour1], isClosed=True, color=(192, 0, 0), thickness=5)

Egy síkidom csúcspontjait egy kontúr tömbben (contour1) fel kell sorolni [x, y] sorrendben. Kitöltött sokszöget a cv2.fillpoly(), sokszög körvonalat a cv2.polylines() függvénnyel rajzolhatunk. Mindkettő második paramétere egy lista (pts), amely kontúr tömböket tartalmaz. Itt akár több kontúrt is felsorolhatunk, viszont akkor is listába kell rendezni, ha csak egy kontúrt akarunk kirajzoltatni.

A körvonal rajzolás esetén meg kell adnunk, hogy zárt-e a kontúr (isClosed). Ha igen, akkor automatikusan összekötésre kerül az utolsó pont a legelsővel. Kitöltött síkidom esetén nyilvánvaló, hogy zárt kell legyen, így nem is kell paraméterként átadni.

Szöveg elhelyezése

cv2.putText(img, 'Szoveg', (bazispont_x, bazispont_y), font, betumeret, (b, g, r), vastagsag, vonaltipus)

A bázispont a szöveg kezdőpontját adja. A karakterek a bázisvonalra kerülnek, vagyis ez az első karakter bal alsó pontja. Ne feledjük, hogy bizonyos betűk szára a bázisvonal alá lóghat!

A font a betűtípus azonosítója. Az OpenCV dokumentációban találunk használható konstansokat (pl. cv2.FONT_HERSHEY_SIMPLEX, cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, ...).

A vonaltípus a betűk megrajzolásakor használt vonalak típusát jelenti. Szöveg esetén érdemes a cv2.LINE_AA használata a szebb eredményhez.

További rajzoló függvények (angol nyelvű dokumentáció)

02_04_ocv_draw_circle.py

# OpenCV2 képmátrix létrehozása, megjelenítése és fájlba mentése
# OpenCV online dokumentáció: https://docs.opencv.org/

# Modul definíciók importálása
import numpy as np

import cv2

# 320x200x3 méretű Numpy tömb létrehozása RGB színes képnek
img = np.ndarray((200, 320, 3), np.uint8)

# Feltöltés 192 (világosszürke) színnel
img.fill(192)

# Kör rajzolása az (50, 100) középponttal, 40 sugárral, vörös színnel, kitöltve
cv2.circle(img, (50, 100), 40, (0, 0, 192), -1)

# További rajzoló függvények:
# https://docs.opencv.org/4.5.1/dc/da5/tutorial_py_drawing_functions.html

# Kép megjelenítése ablakban
cv2.imshow('image', img)

cv2.waitKey(0)

# Kép mentése fájlba
cv2.imwrite('ocv_test1_out.png', img)


# Összes ablak bezárása
cv2.destroyAllWindows()

Eredmény

Feladat

Rajzoljunk geometriai elemeket és írjunk szöveget a képmátrixba!

  • Rajzoljunk pálcikaemberkét és írjuk ki szövegként a nevét!
  • Rajzoljunk stilizált autót és írjuk ki szövegként a rendszámát!
  • Rajzoljunk stilizált házat, a homlokzaton házszámmal!
  • Töltsünk be egy meglévő képet és annotáljuk geometriai elemekkel!

A rajzokat többféle geometriából építsük fel! Használjunk eltérő színeket, vonalvastagságokat! A szöveg megfelelően legyen pozícionálva és ne lógjon ki a képmátrixból!