Asosiy qismga o'tish

Chizish va annotatsiya: shakl, matn, maska

3-bob 5 kod bloki 1368 so'z

Nega analitikka chizish kerak

Model "bu yerda odam bor" deb aytdi — buni ko'rsatish kerak: box chizish, yozuv qo'yish, ishonch foizini yozish. Har bir obyekt aniqlash loyihasining oxirgi qadami shu. Shuning uchun chizish funksiyalari OpenCV da sodda va tez.

Hamma chizish funksiyasi rasmni joyida o'zgartiradi (2-bob: ROI nusxa emas). Asl rasm kerak bo'lsa, avval copy().

To'rtta asosiy funksiya

python8 qator
img = cv2.imread(str(RASM / "qurilish_kichik.jpg"))
tuval = img.copy()
cv2.rectangle(tuval, (300, 150), (560, 330), (0, 255, 0), 3)          # (x1,y1), (x2,y2), rang, qalinlik
cv2.circle(tuval, (700, 260), 45, (0, 165, 255), -1)                   # -1 = ichini to'ldirish
cv2.line(tuval, (0, 500), (960, 500), (255, 0, 0), 2)
cv2.putText(tuval, "ishchilar: 12", (300, 140), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2, cv2.LINE_AA)
ko_rsat(tuval, nom="chizish.png", kenglik=9,
        izoh="rectangle, circle, line va putText — rang BGR da: (0,255,0) yashil, (0,165,255) to'q sariq.")

rectangle, circle, line va putText — rang BGR da: (0,255,0) yashil, (0,165,255) to'q sariq.

rectangle, circle, line va putText — rang BGR da: (0,255,0) yashil, (0,165,255) to'q sariq.

Umumiy qoidalar:

Argument Ma'nosi
Koordinata (x, y) — piksel indeksining teskarisi (img[y, x]). Chizishda x oldin
Rang BGR uchligi; kulrang rasmda bitta son
Qalinlik Piksel; -1 (yoki cv2.FILLED) — ichini to'ldiradi
lineType cv2.LINE_AA — silliq chekka (antialias), matn uchun doim shuni oling

:::gotcha Koordinata tartibi ikki xil Massiv indeksi img[y, x], chizish funksiyalari esa (x, y). Bitta faylda ikkalasi ham ishlatiladi. Box ni (x1, y1, x2, y2) deb saqlang va kesishda img[y1:y2, x1:x2] deb yozing — shunda chalkashmaysiz. :::

Matnni o'qiladigan qilish

Rasm ustidagi yozuv ko'pincha fonga qo'shilib ketadi. Yechim — matn ortiga to'ldirilgan to'rtburchak:

python12 qator
def yozuv(rasm, matn, joy, rang=(0, 255, 0), katta=0.8):
    (w, h), asos = cv2.getTextSize(matn, cv2.FONT_HERSHEY_SIMPLEX, katta, 2)
    x, y = joy
    cv2.rectangle(rasm, (x - 4, y - h - 6), (x + w + 4, y + asos), (0, 0, 0), -1)
    cv2.putText(rasm, matn, (x, y), cv2.FONT_HERSHEY_SIMPLEX, katta, rang, 2, cv2.LINE_AA)

a, b = img.copy(), img.copy()
cv2.putText(a, "kaskasiz odam", (60, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2, cv2.LINE_AA)
yozuv(b, "kaskasiz odam", (60, 60), (0, 255, 255))
ko_rsat(a[0:110, 0:420], b[0:110, 0:420], nom="matn_fon.png",
        sarlavhalar=["fonsiz — ochiq joyda yo'qoladi", "fon bilan — har doim o'qiladi"],
        izoh="getTextSize matnning o'lchamini oldindan aytadi, shuning uchun ortiga aniq o'lchamli fon chiziladi.")

getTextSize matnning o'lchamini oldindan aytadi, shuning uchun ortiga aniq o'lchamli fon chiziladi.

getTextSize matnning o'lchamini oldindan aytadi, shuning uchun ortiga aniq o'lchamli fon chiziladi.

cv2.putText kirill va o'zbek maxsus harflarini (o', g') chizmaydi — OpenCV shriftlari faqat ASCII. Agar o'zbekcha yozuv kerak bo'lsa, Pillow bilan chizib, keyin massivga qaytarish kerak.

Maska: rasmning faqat kerakli qismi

Maska — bir kanalli rasm, unda 255 "bu joy kerak", 0 "kerak emas" degani. Maska bilan istalgan shakldagi sohani ajratish mumkin:

python7 qator
maska = np.zeros(img.shape[:2], np.uint8)
cv2.circle(maska, (480, 270), 150, 255, -1)
cv2.rectangle(maska, (700, 350), (900, 480), 255, -1)
faqat_maska = cv2.bitwise_and(img, img, mask=maska)
print("maskadagi piksellar:", int((maska > 0).sum()), f"({100 * (maska > 0).mean():.1f}%)")
ko_rsat(maska, faqat_maska, nom="maska.png", sarlavhalar=["maska (255 = kerak)", "bitwise_and natijasi"],
        izoh="Doira va to'rtburchak birlashtirildi: shakl istalgancha murakkab bo'lishi mumkin.")
Chiqish
maskadagi piksellar: 97012 (18.7%)

Doira va to'rtburchak birlashtirildi: shakl istalgancha murakkab bo'lishi mumkin.

Doira va to'rtburchak birlashtirildi: shakl istalgancha murakkab bo'lishi mumkin.

cv2.bitwise_and(img, img, mask=maska) — maskada 0 bo'lgan joyni qora qiladi, qolganini saqlaydi. Boshqa bitwise amallar: bitwise_or, bitwise_xor, bitwise_not (maskani teskari qilish).

Amaliy misol: yuzni xiralashtirish

Maxfiylik uchun eng ko'p ishlatiladigan naqsh (YOLO kitobidagi qoida: hodisa uchun yuz kerak emas):

python12 qator
def yuzni_yashir(rasm, box, kuch=25):
    x1, y1, x2, y2 = box
    soha = rasm[y1:y2, x1:x2]
    rasm[y1:y2, x1:x2] = cv2.GaussianBlur(soha, (0, 0), kuch)
    return rasm

xira = img.copy()
for box in [(352, 175, 392, 215), (452, 168, 492, 208), (560, 180, 600, 220)]:
    yuzni_yashir(xira, box)
ko_rsat(img[150:260, 320:640], xira[150:260, 320:640], nom="xiralashtirish.png",
        sarlavhalar=["asl", "boshlar xiralashtirilgan"],
        izoh="GaussianBlur ning sigma si katta bo'lsa, qaytarib tiklab bo'lmaydi. Pikselli (mozaikali) usul esa tiklanishi mumkin.")

GaussianBlur ning sigma si katta bo'lsa, qaytarib tiklab bo'lmaydi. Pikselli (mozaikali) usul esa tiklanishi mumkin.

GaussianBlur ning sigma si katta bo'lsa, qaytarib tiklab bo'lmaydi. Pikselli (mozaikali) usul esa tiklanishi mumkin.

Mozaika (resize bilan kichraytirib, qayta kattalashtirish) chiroyli ko'rinadi, lekin zaifroq: katak o'lchami kichik bo'lsa, tasvirni qisman tiklash mumkin. Maxfiylik uchun kuchli Gauss blur ishlating.

Shaffof qatlam: addWeighted

Zonani belgilash uchun yarim shaffof to'ldirish qulay:

python8 qator
asos = img.copy()
qatlam = img.copy()
zona = np.array([[120, 480], [420, 360], [700, 400], [640, 520]], np.int32)
cv2.fillPoly(qatlam, [zona], (0, 0, 255))
aralash = cv2.addWeighted(qatlam, 0.35, asos, 0.65, 0)                 # 35% qatlam + 65% asl
cv2.polylines(aralash, [zona], True, (0, 0, 255), 2)
ko_rsat(aralash, nom="zona.png", kenglik=9,
        izoh="addWeighted(a, alpha, b, beta, gamma): natija = a*alpha + b*beta + gamma. Zona ichi ko'rinib turadi.")

addWeighted(a, alpha, b, beta, gamma): natija = a*alpha + b*beta + gamma. Zona ichi ko'rinib turadi.

addWeighted(a, alpha, b, beta, gamma): natija = a*alpha + b*beta + gamma. Zona ichi ko'rinib turadi.

Bu — "taqiqlangan zona" belgilashning standart usuli: ichidagi narsa ko'rinib turadi, chegara esa aniq.

Xulosa

Tushuncha Asosiy fikr
Chizish joyida ishlaydi Asl kerak bo'lsa copy()
Koordinata Chizishda (x, y), indeksda [y, x]
-1 qalinlik Ichini to'ldiradi
LINE_AA Silliq chekka; matn uchun majburiy odat
getTextSize Matn ortiga aniq o'lchamli fon chizish uchun
Maska 255/0 li bir kanalli rasm + bitwise_and
Maxfiylik Kuchli Gauss blur; mozaika zaifroq
addWeighted Yarim shaffof qatlam: zona, issiqlik xaritasi

Talaba ishi

  1. yozuv funksiyasiga fon rangini avtomatik tanlashni qo'shing: agar o'sha joyning o'rtacha yorqinligi 127 dan katta bo'lsa — qora fon, aks holda oq. (getTextSize bilan sohani oling, mean() bilan o'lchang.)
  2. Uchta box uchun "ishonch" foizini ham yozing (0.92 kabi) va foizga qarab rangni o'zgartiring: 0.9 dan yuqori — yashil, 0.7–0.9 — sariq, pastrog'i — qizil.
  3. Maska yasang: rasmning faqat pastki uchdan biri va o'ng yarmi kesishgan joyi ko'rinsin. Qaysi bitwise amal kerak?
  4. addWeighted da alpha ni 0.1 dan 0.9 gacha o'zgartirib, qaysi qiymatda zona ham ko'rinadigan, ham xalaqit bermaydigan bo'lishini toping. Javobingizni bitta rasmda 4 variant bilan ko'rsating.

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar