Asosiy qismga o'tish

OpenCV bilan tanishuv: o'qish, ko'rsatish, saqlash

1-bob 8 kod bloki 1287 so'z

Nega OpenCV

Kompyuterga rasmni "ko'rsatish" — bu unga sonlar massivini berish. OpenCV o'sha massiv ustida ishlaydigan kutubxona: o'qish, o'zgartirish, o'lchash, videodan kadr olish. Yadrosi C++ da yozilgan, shuning uchun tez — real vaqtda, kameradan sekundiga 30 kadr kelayotganda ham ulguradi.

Kutubxona Apache-2.0 litsenziyasida: tijorat mahsulotida ham bepul ishlatiladi, faqat mualliflik yozuvini saqlash kerak. Bu — chuqur o'rganish modellari bilan solishtirganda muhim farq (ba'zi modellar tijoratga ruxsat bermaydi).

OpenCV nimani yaxshi qiladi va nimani qilmaydi:

Yaxshi qiladi Boshqa vosita kerak
Rasmni o'qish, o'lchash, kesish, burish Rasmda "bu mushukmi yoki itmi" degan savol — neyron tarmoq
Rang, chekka, kontur, shakl — geometriya Matnni o'qish (OCR) — Tesseract yoki maxsus model
Videodan kadr olish, kamerani boshqarish Katta hajmli modelni o'qitish — PyTorch
Tezkor tayyorlash (preprocessing) Murakkab semantik tahlil

Amalda OpenCV ko'pincha quvurning birinchi qismi bo'ladi: rasmni tozalaydi, kerakli joyini kesadi, keyin model ishlaydi. Shuning uchun uni o'rganish — modelni o'rganishdan oldingi qadam.

O'rnatish: uchta paket, bittasini tanlang

bash3 qator
pip install opencv-python              # asosiy; deyarli hamma kerakli narsa shu yerda
pip install opencv-contrib-python      # asosiy + qo'shimcha modullar (SIFT, tracker lar, aruco)
pip install opencv-python-headless     # oynasiz: server va Docker uchun (imshow ishlamaydi)

Uchalasini birga o'rnatmang — ular bir-birining ustiga yozadi va tushunarsiz xatolar beradi. Serverda (masalan, Django ichida) headless ni oling: u oyna kutubxonalarini talab qilmaydi va tasvir hajmi kichik.

Tekshiramiz:

python3 qator
import cv2
print("OpenCV versiyasi:", cv2.__version__)
print("Haar fayllari papkasi bormi:", bool(cv2.data.haarcascades))
Chiqish
OpenCV versiyasi: 4.10.0
Haar fayllari papkasi bormi: True

Birinchi dastur: o'qish, o'lchash, saqlash

python6 qator
img = cv2.imread(str(RASM / "qurilish_kichik.jpg"))
print("turi:", type(img).__name__, "| shakli:", img.shape, "| dtype:", img.dtype)
print("balandlik:", img.shape[0], "| kenglik:", img.shape[1], "| kanallar:", img.shape[2])
print("jami piksel:", img.shape[0] * img.shape[1], "| xotirada:", img.nbytes // 1024, "KB")
cv2.imwrite(str(RASM / "_nusxa.jpg"), img, [cv2.IMWRITE_JPEG_QUALITY, 80])
print("saqlandi, hajmi:", (RASM / "_nusxa.jpg").stat().st_size // 1024, "KB")
Chiqish
turi: ndarray | shakli: (540, 960, 3) | dtype: uint8
balandlik: 540 | kenglik: 960 | kanallar: 3
jami piksel: 518400 | xotirada: 1518 KB
saqlandi, hajmi: 104 KB

Uch narsaga e'tibor bering. Birinchisi: imread oddiy NumPy massivi qaytaradi — demak OpenCV bilmagan har qanday amalni NumPy bilan qilish mumkin. Ikkinchisi: shakl (balandlik, kenglik, kanal) tartibida, ya'ni avval qator, keyin ustun — matematikadagi jadval tartibi, (x, y) emas. Uchinchisi: dtype — uint8, har kanal 0 dan 255 gacha.

Saqlashda sifat ham muhim: yuqorida JPEG sifati 80 ga qo'yildi va fayl asl hajmidan kichrayadi. PNG uchun cv2.IMWRITE_PNG_COMPRESSION (0–9) bor; PNG yo'qotishsiz, JPEG esa yo'qotish bilan siqadi.

Eng ko'p uchraydigan birinchi xato: fayl topilmasa

python3 qator
yoq = cv2.imread(str(RASM / "bunday_fayl_yoq.jpg"))
print("natija:", yoq)
print("xato chiqdimi?", "yo'q — jim None qaytdi")
Chiqish
natija: None
xato chiqdimi? yo'q — jim None qaytdi

imread fayl topilmasa xato bermaydi, None qaytaradi. Keyingi qatorda img.shape yozsangiz, AttributeError: 'NoneType' object has no attribute 'shape' chiqadi va yangi boshlovchi uni "OpenCV buzuq" deb tushunadi. Har doim tekshiring:

python3 qator
img = cv2.imread(yol)
if img is None:
    raise FileNotFoundError(yol)

Sabablari: noto'g'ri yo'l, kirill yoki bo'shliqli papka nomi, fayl haqiqatan rasm emas, yoki ruxsat yo'q.

BGR tuzog'i

OpenCV rangni BGR tartibida saqlaydi (ko'k, yashil, qizil), matplotlib va deyarli hamma boshqa kutubxona esa RGB kutadi. Shuning uchun OpenCV bilan o'qilgan rasmni to'g'ridan-to'g'ri matplotlib ga bersangiz, ranglar almashib ketadi:

python5 qator
import matplotlib.pyplot as plt
f, ax = plt.subplots(1, 2, figsize=(11, 3.4))
ax[0].imshow(img); ax[0].set_title("to'g'ridan-to'g'ri (BGR) — ranglar noto'g'ri", fontsize=10); ax[0].axis("off")
ax[1].imshow(img[:, :, ::-1]); ax[1].set_title("[:, :, ::-1] bilan RGB — to'g'ri", fontsize=10); ax[1].axis("off")
fig("bgr_rgb.png", "Bitta rasm, ikki xil tartib. Chapda ko'k va qizil almashgan: osmon va kiyimlarga qarang.")

Bitta rasm, ikki xil tartib. Chapda ko'k va qizil almashgan: osmon va kiyimlarga qarang.

Bitta rasm, ikki xil tartib. Chapda ko'k va qizil almashgan: osmon va kiyimlarga qarang.

Tuzatishning ikki yo'li bor: img[:, :, ::-1] (kanallarni teskari o'qish, nusxa olmaydi) yoki cv2.cvtColor(img, cv2.COLOR_BGR2RGB) (aniq va o'qilishi oson). Ikkalasi bir xil natija beradi.

Nega shunday? OpenCV 2000-yillarda yozilgan, o'sha paytdagi kameralar va BMP formati BGR ishlatardi. Keyin o'zgartirish mumkin emas edi: dunyodagi millionlab qator kod buzilardi.

:::gotcha Rasmni faylga saqlaganda teskari qilmang cv2.imwrite o'zi BGR kutadi. Agar siz matplotlib uchun RGB ga o'girgan massivni imwrite ga bersangiz, saqlangan faylda ranglar almashgan bo'ladi. Qoida: ichkarida BGR, faqat ko'rsatishdan oldin RGB. :::

Ekranda ko'rsatish: imshow va kitobdagi usul

Kompyuterda ishlaganda rasmni alohida oynada ko'rsatish qulay:

python3 qator
cv2.imshow("Rasm", img)      # oyna ochiladi
cv2.waitKey(0)               # 0 = tugma bosilguncha kutadi; 25 = 25 ms kutadi (video uchun)
cv2.destroyAllWindows()      # oynalarni yopadi

waitKey ni unutsangiz oyna qotib qoladi — bu klassik boshlang'ich xato. Server yoki Docker ichida esa imshow umuman ishlamaydi (oyna tizimi yo'q), shuning uchun bu kitobda hamma rasm faylga saqlanadi va matplotlib bilan ko'rsatiladi. Kitob kodini serverda ham, noutbukda ham ishlatish mumkin bo'lsin.

Keyingi boblarda ko'p rasmni yonma-yon solishtiramiz, shuning uchun kichik yordamchi ishlatamiz:

python5 qator
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ko_rsat(img, gray, nom="rangli_va_kulrang.png",
        sarlavhalar=["rangli (3 kanal)", "kulrang (1 kanal)"],
        izoh="ko_rsat() — kitobdagi yordamchi: BGR ni o'zi RGB ga o'giradi, kulrang rasmni gray palitrada chizadi.")
print("rangli:", img.shape, img.nbytes // 1024, "KB   |   kulrang:", gray.shape, gray.nbytes // 1024, "KB")
Chiqish
rangli: (540, 960, 3) 1518 KB   |   kulrang: (540, 960) 506 KB

ko_rsat() — kitobdagi yordamchi: BGR ni o'zi RGB ga o'giradi, kulrang rasmni gray palitrada chizadi.

ko_rsat() — kitobdagi yordamchi: BGR ni o'zi RGB ga o'giradi, kulrang rasmni gray palitrada chizadi.

Kulrang rasm uch barobar kam joy oladi: uchta kanal o'rniga bitta. Shuning uchun chekka topish, kontur va shablon qidirish kabi amallar deyarli har doim kulrang rasmda bajariladi — natija bir xil, hisob uch barobar tez.

Xulosa

Tushuncha Asosiy fikr
Rasm = massiv imread NumPy massivi qaytaradi: (balandlik, kenglik, kanal), uint8
Uch paket opencv-python, -contrib- (qo'shimcha modullar), -headless (server) — faqat bittasi
imread jim Fayl yo'q bo'lsa None, xato emas. Har doim tekshiring
BGR OpenCV ichida BGR; ko'rsatishdan oldin RGB ga o'giring, saqlashdan oldin o'girmang
imshow Faqat oyna bor muhitda; serverda faylga saqlang
Kulrang Uch barobar kam xotira, ko'p amal uchun yetarli

Talaba ishi

  1. O'z telefoningizdagi bitta suratni o'qing va shakli, dtype va xotiradagi hajmini chiqaring. 12 MP surat xotirada necha MB joy oladi? Fayl hajmi bilan solishtiring — nega farq bor?
  2. Shu suratni JPEG sifati 95, 60 va 25 bilan saqlang. Fayl hajmlari qanday o'zgaradi? 25 sifatda qaysi joylarda buzilish ko'rinadi (osmon, matn, teri)?
  3. cv2.imread(yol, cv2.IMREAD_GRAYSCALE) bilan o'qing va cvtColor bilan kulrangga o'girilgan variantni solishtiring: natijalar bir xilmi? (np.array_equal bilan tekshiring.)
  4. Kirill yoki bo'shliqli papka nomi bilan sinab ko'ring: imread ishladimi? Xatoni qanday tutasiz?

Bu bobni bepul o'qidingiz.

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

Telegramda yozish Narxlar