Rasm ichida nima bor: piksel, kanal, ROI
Bitta piksel — uchta son
Rangli rasm — bu uch o'lchamli massiv. Har bir katak (piksel) uchta sondan iborat: ko'k, yashil, qizil. Bittasini ochib ko'ramiz:
img = cv2.imread(str(RASM / "qurilish_kichik.jpg")) piksel = img[270, 480] print("img[270, 480] =", piksel, "-> B =", piksel[0], "G =", piksel[1], "R =", piksel[2]) print("faqat qizil kanal:", img[270, 480, 2]) print("eng chap yuqori piksel:", img[0, 0], "| eng o'ng past:", img[-1, -1])
img[270, 480] = [82 68 56] -> B = 82 G = 68 R = 56 faqat qizil kanal: 56 eng chap yuqori piksel: [121 117 89] | eng o'ng past: [75 62 54]
Indeks tartibi — img[qator, ustun], ya'ni avval y, keyin x. Bu deyarli har bir yangi boshlovchining
birinchi xatosi: img[x, y] deb yozib, boshqa joyning rangini oladi yoki IndexError oladi.
Qiymatlar 0–255 oralig'ida (uint8). 0 — qorong'i, 255 — yorqin. Uchala kanal teng bo'lsa — kulrang tus:
[200, 200, 200] och kulrang, [30, 30, 30] deyarli qora.
Kanallarni ajratish
b, g, r = cv2.split(img) print("har kanal shakli:", b.shape, "| dtype:", b.dtype) print(f"o'rtacha qiymat -> ko'k {b.mean():.0f}, yashil {g.mean():.0f}, qizil {r.mean():.0f}") ko_rsat(b, g, r, nom="kanallar.png", sarlavhalar=["ko'k kanal", "yashil kanal", "qizil kanal"], izoh="Har kanal alohida kulrang rasm. Osmon ko'k kanalda yorqin, o'simlik yashilda, sariq kaskalar qizil va yashilda.")
har kanal shakli: (540, 960) | dtype: uint8 o'rtacha qiymat -> ko'k 122, yashil 114, qizil 103

Har kanal alohida kulrang rasm. Osmon ko'k kanalda yorqin, o'simlik yashilda, sariq kaskalar qizil va yashilda.
Har kanal — alohida bir kanalli rasm. Qaysidir kanalda kerakli obyekt yaxshiroq ajralib tursa, keyingi ish o'sha kanalda qilinadi. Masalan sariq kaska qizil va yashil kanalda yorqin, ko'kda qorong'i.
Teskarisi — cv2.merge([b, g, r]). Kanallarni ataylab almashtirib ko'ramiz:
almashgan = cv2.merge([r, g, b]) # qizil va ko'kni joyini almashtirdik farq = int(np.abs(img.astype(int) - almashgan.astype(int)).mean()) print("o'rtacha farq (0-255):", farq) ko_rsat(img, almashgan, nom="almashgan.png", sarlavhalar=["asl (BGR)", "R va B almashgan"], izoh="Bu — 1-bobdagi BGR tuzog'ining aynan o'zi, faqat bu safar ataylab qilindi.")
o'rtacha farq (0-255): 16

Bu — 1-bobdagi BGR tuzog'ining aynan o'zi, faqat bu safar ataylab qilindi.
ROI: rasmning bir qismi
ROI (region of interest) — qiziqish sohasi. NumPy kesimi bilan olinadi va bu nusxa emas, o'sha massivning bir qismi:
roi = img[150:330, 300:560] # [y1:y2, x1:x2] print("ROI shakli:", roi.shape, "| asl rasmning", f"{100 * roi.size / img.size:.1f}%") nusxa = img.copy() nusxa[150:330, 300:560] = cv2.GaussianBlur(roi, (0, 0), 8) # faqat shu joyni xiralashtirdik ko_rsat(roi, nusxa, nom="roi.png", sarlavhalar=["ROI: kesib olingan qism", "shu qism xiralashtirilgan"], izoh="ROI ni o'zgartirish butun rasmni o'zgartiradi — chunki u nusxa emas, ko'rinish (view).")
ROI shakli: (180, 260, 3) | asl rasmning 9.0%

ROI ni o'zgartirish butun rasmni o'zgartiradi — chunki u nusxa emas, ko'rinish (view).
Bu xususiyat foydali ham, xavfli ham. Foydali: yuzni xiralashtirish, raqamni yashirish, faqat bitta zonani
qayta ishlash. Xavfli: asl rasmni saqlab qo'ymoqchi bo'lsangiz, img.copy() yozishni unutmang — aks holda
asl ma'lumot yo'qoladi.
:::tip Nusxa qachon kerak
b = a — ikkala nom bitta massivga qaraydi. b = a.copy() — haqiqiy nusxa. Kesim (a[10:20]) ham nusxa
emas. Funksiyaga rasm berayotganda, funksiya uni o'zgartirishi mumkinligini o'ylang.
:::
Rasm yaratish va to'ldirish
Rasm oddiy massiv bo'lgani uchun uni noldan yasash mumkin:
tuval = np.zeros((200, 400, 3), np.uint8) # qora tuval tuval[:, :200] = (255, 0, 0) # chap yarmi — ko'k (BGR!) tuval[:, 200:] = (0, 165, 255) # o'ng yarmi — to'q sariq oq = np.full((200, 400, 3), 255, np.uint8) ko_rsat(tuval, oq, nom="tuval.png", sarlavhalar=["np.zeros bilan yasalgan", "np.full(255) — oq"], izoh="(255, 0, 0) — ko'k, chunki tartib BGR. RGB da o'ylab yozsangiz, rang boshqa chiqadi.") print("tuval dtype:", tuval.dtype, "| min:", tuval.min(), "| max:", tuval.max())
tuval dtype: uint8 | min: 0 | max: 255

(255, 0, 0) — ko'k, chunki tartib BGR. RGB da o'ylab yozsangiz, rang boshqa chiqadi.
dtype tuzog'i: 250 + 10 = 4
Piksel uint8 — 0 dan 255 gacha. 255 dan oshsa, hisob boshidan boshlanadi (o'ralib ketadi):
a = np.uint8([250]) print("NumPy bilan 250 + 10 =", (a + 10)[0], " <- o'ralib ketdi (260 - 256)") print("cv2.add bilan =", cv2.add(a, 10)[0], " <- 255 da to'xtadi (to'yingan qo'shish)") yorqin_numpy = img + 60 yorqin_cv2 = cv2.add(img, 60) ko_rsat(yorqin_numpy, yorqin_cv2, nom="uint8_tuzoq.png", sarlavhalar=["img + 60 (NumPy) — dog'lar paydo bo'ldi", "cv2.add(img, 60) — to'g'ri"], izoh="Yorqin joylar 255 dan oshib, qora dog'ga aylandi. Yorug'likni o'zgartirishda cv2.add ishlating.")
NumPy bilan 250 + 10 = 4 <- o'ralib ketdi (260 - 256) cv2.add bilan = [260.] <- 255 da to'xtadi (to'yingan qo'shish)

Yorqin joylar 255 dan oshib, qora dog'ga aylandi. Yorug'likni o'zgartirishda cv2.add ishlating.
Chapdagi rasmda osmon va yorqin beton qora dog'lar bilan qoplangan: 255 dan oshgan piksellar nolga tushib
ketgan. O'ngda cv2.add ishlatilgan — u 255 da to'xtaydi.
Qoida: yorug'lik va rang ustida ishlaganda OpenCV funksiyalarini ishlating (cv2.add, cv2.subtract,
cv2.addWeighted). NumSharp arifmetikasi faqat siz o'ralishni xohlaganingizda to'g'ri.
Rasm haqida qisqa hisobot
Amalda har yangi rasm bilan ishlashdan oldin shu to'rt raqamga qaraladi:
def rasm_haqida(nom): im = cv2.imread(str(RASM / nom)) g = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) return {"fayl": nom, "kenglik": im.shape[1], "balandlik": im.shape[0], "o'rtacha yorqinlik": round(float(g.mean()), 1), "kontrast (std)": round(float(g.std()), 1), "to'yingan piksel %": round(float(((g == 0) | (g == 255)).mean() * 100), 2)} show(pd.DataFrame([rasm_haqida(n) for n in ["qurilish_kichik.jpg", "past_kontrast.jpg", "hujjat.jpg", "shakllar.png"]]))
| fayl | kenglik | balandlik | o'rtacha yorqinlik | kontrast (std) | to'yingan piksel % |
|---|---|---|---|---|---|
| qurilish_kichik.jpg | 960 | 540 | 111.6 | 49.2 | 0 |
| past_kontrast.jpg | 960 | 540 | 138.4 | 20.6 | 0 |
| hujjat.jpg | 800 | 1 000 | 155.7 | 90.2 | 25.69 |
| shakllar.png | 640 | 480 | 216.1 | 52 | 0 |
Nima ko'rinadi: past_kontrast.jpg ning standart chetlanishi 20.6 — asl rasmning 49.2 sidan ikki barobardan
ko'p kichik. Demak rasm "yuvilgan", tafsilot kam (11-bobda uni tuzatamiz). hujjat.jpg da esa kontrast eng
katta (90.2): oq varaq va qora fon — ikki chekka. O'sha faylda to'yingan piksel 25.7%: chorak rasm 0 yoki
255 ga tiqilgan, ya'ni o'sha joylarda ma'lumot yo'q — na yorug'lashtirish, na qorong'ilashtirish uni tiklaydi.
Xulosa
| Tushuncha | Asosiy fikr |
|---|---|
| Indeks | img[y, x] — avval qator, keyin ustun |
| Piksel | 3 ta uint8: B, G, R. Teng bo'lsa — kulrang tus |
split / merge |
Kanallarni ajratish va yig'ish; obyekt qaysi kanalda yaxshi ko'rinsa, o'sha kanalda ishlang |
| ROI | img[y1:y2, x1:x2] — nusxa emas; o'zgartirsangiz asl rasm o'zgaradi |
copy() |
Asl kerak bo'lsa — nusxa oling |
uint8 o'ralishi |
img + 60 dog' beradi, cv2.add(img, 60) to'g'ri ishlaydi |
| Tez tekshiruv | O'lcham, o'rtacha yorqinlik, kontrast, to'yingan piksel foizi |
Talaba ishi
qurilish.jpg(katta versiya) ning markazidagi 300x300 kvadratni kesib oling va alohida faylga saqlang. Markazni qanday hisoblaysiz —shapedan.- Faqat qizil kanalni nolga tenglashtiring va natijani ko'ring. Rasm qanday o'zgardi? Qaysi obyektlar yo'qoldi?
img - 60vacv2.subtract(img, 60)ni solishtiring. Qorong'i joylarda nima farq bor?rasm_haqidafunksiyasiga "eng ko'p uchraydigan rang" ustunini qo'shing (maslahat:np.uniqueyoki kanallarni 32 ga bo'lib guruhlash).shakllar.pnguchun javob nima?
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.