Bozor va narx: bitta kamera qancha turadi
Bu bobning kodi: kod/25_narx.py — kitob papkasidan ishga tushiring: python kod/25_narx.py
Mijoz birinchi bo'lib "qancha turadi?" deb so'raydi. Javob ikki tomondan quriladi: tannarx — bizga bitta kamera oyiga qanchaga tushadi, va qiymat — mijoz nima uchun pul to'laydi. Bu bobda tannarxni o'lchaymiz, taxmin qilmaymiz: 22-bobdagi kaska tizimi bitta kompyuterda nechta kamerani ko'taradi, qancha quvvat oladi va O'zbekistondagi narxlarda bu qanchaga tushadi.
Narxlar 2026-09-22 holatida: uskuna — asaxiy.uz, dollar kursi — Markaziy bank, elektr tarifi — Vazirlar Mahkamasining 2026-05-15 dagi 243-son qarori. Narxlar o'zgaradi — hisob-kitob kodi shuning uchun parametrlar bilan yozilgan.
Nega 18-bobdagi raqam yaramaydi
18-bobda bitta kompyuter ~70 ta kamerani 15 fps da ko'tardi. U odam aniqlash uchun edi: YOLO11n, 384x640, TensorRT, katta batch. 22-bobdagi kaska quvuri boshqa ish qiladi:
- 2560x1440 kadrni dekodlaydi;
- odamlarni 1280 da qidiradi (kichik odam ham ko'rinsin, 17-bob);
- BoT-SORT bilan kuzatadi, kamera harakatini (GMC) hisobga olib;
- har bir odam uchun asl kadrdan qirqim olib, kaska modelini ishlatadi.
Narx vazifaga bog'liq: "nechta odam o'tdi" va "kim kaskasiz" — bir xil kamera, lekin tannarxi boshqa. Shuning uchun aynan sotiladigan quvurni o'lchaymiz.
Yuklama sinovi
Ishchi 22-bobdagi quvurni oladi (kaskasizmi — 22-bobdan), faqat kadrni RTSP dan emas, videofayldan o'qiydi va iloji boricha tez ishlaydi. Har bir bosqich vaqtini alohida sanaydi. Bir nechta ishchini bir vaqtda boshlash uchun u "tayyor" deb yozib, buyruq kutadi — shunda hamma ishchi o'lchovni bir paytda boshlaydi.
# Yuklama ishchisi: 22-bobdagi kaska quvuri videofayldan, iloji boricha tez. "tayyor" dan keyin Enter kutadi, # --soniya davomida kadrlarni sanaydi va JSON chiqaradi (kadr/s va har bosqich uchun ms). import argparse import json import os import sys import time import cv2 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from ultralytics import YOLO # noqa: E402 from ultralytics.trackers import BOTSORT # noqa: E402 from ultralytics.utils import LOGGER, YAML, IterableSimpleNamespace # noqa: E402 from ultralytics.utils.checks import check_yaml # noqa: E402 LOGGER.setLevel("ERROR") kaskasizmi = __import__("22_qurilish_ishchi").kaskasizmi def main(): p = argparse.ArgumentParser() p.add_argument("--video", default="datasets/pexels/13921040_2560x1440.mp4") p.add_argument("--gmc", default="sparseOptFlow", help="none — qo'zg'almas kamera") p.add_argument("--soniya", type=float, default=15) p.add_argument("--qizdirish", type=int, default=20, help="o'lchovdan oldingi kadrlar") a = p.parse_args() odam, ppe = YOLO("weights/yolo11n.pt"), YOLO("out/train/ppe_coco/weights/best.pt") sozlama = YAML.load(check_yaml("botsort.yaml")) | {"gmc_method": a.gmc} tracker = BOTSORT(IterableSimpleNamespace(**sozlama), frame_rate=30) video = cv2.VideoCapture(a.video) vaqt = dict.fromkeys(("dekod", "aniqlash", "trek", "kaska"), 0.0) def qadam(): t = [time.perf_counter()] ok, rasm = video.read() if not ok: video.set(cv2.CAP_PROP_POS_FRAMES, 0) ok, rasm = video.read() t.append(time.perf_counter()) r = odam.predict(rasm, imgsz=1280, classes=[0], conf=0.1, device=0, verbose=False)[0] t.append(time.perf_counter()) treklar = tracker.update(r.boxes.cpu().numpy(), rasm) t.append(time.perf_counter()) kaskasizmi(ppe, rasm, treklar) t.append(time.perf_counter()) for k, boshi, oxiri in zip(vaqt, t, t[1:]): vaqt[k] += oxiri - boshi return len(treklar) for _ in range(a.qizdirish): qadam() vaqt.update(dict.fromkeys(vaqt, 0.0)) print("tayyor", flush=True) sys.stdin.readline() kadr = odamlar = 0 t0 = time.time() while time.time() - t0 < a.soniya: odamlar += qadam() kadr += 1 print(json.dumps({"fps": round(kadr / (time.time() - t0), 2), "odam": round(odamlar / kadr, 1), **{k: round(v * 1000 / kadr, 1) for k, v in vaqt.items()}}), flush=True) if __name__ == "__main__": main()
Boshqaruvchi 1, 2, 3, 4, 5, 6 va 8 ta ishchini ishga tushiradi — har ishchi bitta kamera o'rnida — va o'lchov davomida GPU quvvati, bandligi va xotirasini nvidia-smi dan (har 0.5 soniyada), CPU bandligini psutil dan oladi. Ikki holat: kamera harakatini hisobga olish (GMC) yoqilgan — 22-bobdagidek, va o'chirilgan — qo'zg'almas kamera uchun. Avval hech narsa ishlamaganda o'lchaymiz: GPU da boshqa ish ham bo'lishi mumkin (monitor, boshqa dasturlar).
import json import math import subprocess import sys import time import pandas as pd import psutil SMI = ["nvidia-smi", "--query-gpu=power.draw,utilization.gpu,memory.used", "--format=csv,noheader,nounits", "-lms", "500"] def olcha(ish): """ish() davomida: GPU quvvati (W), bandligi (%), xotirasi (MB) — o'rtacha; CPU bandligi (%).""" smi = subprocess.Popen(SMI, stdout=subprocess.PIPE, text=True) psutil.cpu_percent() natija = ish() cpu = psutil.cpu_percent() smi.terminate() q = [list(map(float, s.split(","))) for s in smi.communicate()[0].splitlines()[2:] if s.strip()] return natija, cpu, [sum(x[i] for x in q) / len(q) for i in range(3)] def yuklama(k, gmc): ishchilar = [subprocess.Popen([sys.executable, "kod/25_yuklama.py", "--gmc", gmc], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True) for _ in range(k)] try: for w in ishchilar: if w.stdout.readline().strip() != "tayyor": raise RuntimeError("ishchi ishga tushmadi") def ish(): for w in ishchilar: w.stdin.write("\n") w.stdin.flush() return [json.loads(w.stdout.readline()) for w in ishchilar] return olcha(ish) finally: for w in ishchilar: w.kill() _, cpu, (vatt, gpu, xotira) = olcha(lambda: time.sleep(10)) qatorlar = [{"GMC": "bo'sh", "ishchi": 0, "jami fps": 0, "fps / ishchi": 0, "CPU %": round(cpu), "GPU %": round(gpu), "GPU W": round(vatt), "GPU xotira, GB": round(xotira / 1024, 1)}] bosqichlar = {} for gmc in ("sparseOptFlow", "none"): for k in (1, 2, 3, 4, 5, 6, 8): r, cpu, (vatt, gpu, xotira) = yuklama(k, gmc) jami = sum(x["fps"] for x in r) qatorlar.append({"GMC": gmc, "ishchi": k, "jami fps": round(jami, 1), "fps / ishchi": round(jami / k, 1), "CPU %": round(cpu), "GPU %": round(gpu), "GPU W": round(vatt), "GPU xotira, GB": round(xotira / 1024, 1)}) if k == 1: bosqichlar[gmc] = {x: r[0][x] for x in ("dekod", "aniqlash", "trek", "kaska")} | {"odam / kadr": r[0]["odam"]} jadval = pd.DataFrame(qatorlar) show(jadval, n=20) show(pd.DataFrame(bosqichlar).T.rename_axis("GMC").reset_index())
| GMC | ishchi | jami fps | fps / ishchi | CPU % | GPU % | GPU W | GPU xotira, GB |
|---|---|---|---|---|---|---|---|
| bo'sh | 0 | 0 | 0 | 2 | 8 | 28 | 1 |
| sparseOptFlow | 1 | 16.3 | 16.3 | 16 | 27 | 88 | 2.9 |
| sparseOptFlow | 2 | 23.5 | 11.8 | 31 | 49 | 119 | 4.6 |
| sparseOptFlow | 3 | 26.4 | 8.8 | 43 | 60 | 132 | 6.5 |
| sparseOptFlow | 4 | 29.8 | 7.5 | 56 | 66 | 142 | 8 |
| sparseOptFlow | 5 | 33.1 | 6.6 | 67 | 72 | 151 | 9.5 |
| sparseOptFlow | 6 | 33.9 | 5.7 | 80 | 74 | 154 | 10.9 |
| sparseOptFlow | 8 | 36.2 | 4.5 | 99 | 78 | 158 | 13.8 |
| none | 1 | 23.2 | 23.2 | 17 | 37 | 113 | 2.8 |
| none | 2 | 31.8 | 15.9 | 32 | 62 | 141 | 4.6 |
| none | 3 | 34.9 | 11.6 | 45 | 72 | 152 | 6.2 |
| none | 4 | 35.8 | 8.9 | 56 | 78 | 158 | 7.9 |
| none | 5 | 37.8 | 7.6 | 68 | 83 | 165 | 9.4 |
| none | 6 | 38.4 | 6.4 | 80 | 84 | 166 | 11 |
| none | 8 | 39.8 | 5 | 99 | 86 | 170 | 14 |
| GMC | dekod | aniqlash | trek | kaska | odam / kadr |
|---|---|---|---|---|---|
| sparseOptFlow | 2.9 | 8.8 | 18.4 | 31.2 | 15 |
| none | 2.5 | 9.2 | 1.4 | 30 | 14.4 |
Jadvallarni o'qiymiz:
- Bitta ishchi GMC bilan 16.3 fps, GMCsiz 23.2 fps beradi. Bu — quvurning o'z tezligi, kadr fayldan keladi. Real tizimda bunga RTSP oqimi, API ga yuborish va boshqa jarayonlar qo'shiladi, shuning uchun bu yerdagi sig'im — yuqori chegara.
- Cheklov protsessorda. Ishchilar ko'paygan sari jami fps o'sadi, lekin sekinlashib boradi: 8 ishchida CPU 99%, GPU esa 78–86%. Bu kompyuterda WSL ga protsessorning 32 ta ipidan 8 tasi berilgan (Intel: 24 yadro, 32 ip) — butun protsessorli Linux server ko'proq ko'taradi. Buni o'z serveringizda o'lchang.
- GPU xotirasi: har ishchi taxminan 1.6–1.9 GB oladi (bo'sh holatda 1.0 GB, 8 ishchida 13.8–14 GB). 16 GB li karta ~8 ishchini sig'diradi, 8 GB li — yarmini.
- Bosqichlar: kaska tekshiruvi kadr vaqtining yarmini (GMC bilan) va 70% ini (GMCsiz) oladi — kadrda ~15 odam, har biriga ~2 ms. Demak, tannarx kadrdagi odamlar soniga bog'liq: gavjum maydon qimmatroq. GMC ~17 ms protsessor vaqti oladi — qo'zg'almas kamerada uni o'chirish mumkin. Dekodlash atigi 2.5–2.9 ms: bu vazifada 18-bobdagi NVDEC katta yutuq bermaydi.
Bitta kompyuter nechta kamera
Kaska uchun har kameraga qancha fps kerak? 22-bobdagi jonli tizim 6.7 fps da ishladi va signallarni to'g'ri berdi. Undan pastini sinamadik, shuning uchun talabni 7 fps deb olamiz. Sig'im — har bir ishchi kamida 7 fps olgan eng ko'p ishchi soni:
KAMERA_FPS = 7 sigim, quvvat = {}, {} for gmc, g in jadval[jadval.ishchi > 0].groupby("GMC", sort=False): mos = g[g["fps / ishchi"] >= KAMERA_FPS] sigim[gmc] = int(mos.ishchi.max()) quvvat[gmc] = int(mos.loc[mos.ishchi.idxmax(), "GPU W"]) print(f"GMC={gmc}: {sigim[gmc]} kamera, GPU {quvvat[gmc]} W")
GMC=sparseOptFlow: 4 kamera, GPU 142 W GMC=none: 5 kamera, GPU 165 W
Kaska nazorati uchun bitta kompyuter 4 ta (harakatlanuvchi kamera) yoki 5 ta (qo'zg'almas kamera) kamerani ko'taradi. 18-bobdagi 70 bilan solishtiring: bir xil kompyuter, bir xil model oilasi, vazifa boshqa — sig'im o'n baravardan ko'p farq qiladi.
Tannarx: kamera boshiga oyiga
Server — o'lchov o'tkazilgan kompyuterning qismlari, asaxiy.uz narxlarida. Kamera — 4 MP (2560x1440) IP kamera: 17-bob bo'yicha kaska uchun shu o'lcham kerak. Protsessorning quvvatini WSL ichidan o'lchab bo'lmaydi — Intel ning rasmiy "Processor Base Power" qiymatini olamiz; bu taxmin. Uskuna 36 oyda o'zini qoplashi kerak deb hisoblaymiz — bu ham qaror, qonun emas.
USD = 11_809.82 # Markaziy bank kursi, 2026-09-22 TARIF = 1_100 # so'm / kVt·soat, VMQ 243-son (2026-05-15), 2026-06-01 dan CPU_W = 125 # i9-14900K "Processor Base Power" (Intel) — o'lchanmagan, taxmin OY_SOAT = 730 MUDDAT_OY = 36 SERVER = {"RTX 5070 Ti 16 GB (ASUS ProArt)": 16_119_000, "Intel Core i9-14900K": 6_249_000, "ona plata Z790": 2_629_000, "64 GB DDR5 (2 x 32 GB)": 2 * 1_829_000, "1 TB NVMe SSD": 799_000, "850 W quvvat bloki": 869_000, "korpus": 709_000, "sovutgich": 559_000} KAMERA = 889_000 # Hikvision DS-2CD2143G0-I, 4 MP server = sum(SERVER.values()) print(f"server: {server:,} so'm (~{server / USD:,.0f} $)".replace(",", " ")) tannarx = {} for gmc, n in sigim.items(): qism = {"server ulushi": server / MUDDAT_OY / n, "kamera": KAMERA / MUDDAT_OY, "elektr": (quvvat[gmc] + CPU_W) * OY_SOAT / 1000 * TARIF / n} tannarx[gmc] = qism | {"jami": sum(qism.values())} show(pd.DataFrame(tannarx).T.round(-3).astype(int).rename_axis("so'm / kamera / oy").reset_index())
server: 31 591 000 so'm (~2 675 $)
| so'm / kamera / oy | server ulushi | kamera | elektr | jami |
|---|---|---|---|---|
| sparseOptFlow | 219 000 | 25 000 | 54 000 | 298 000 |
| none | 176 000 | 25 000 | 47 000 | 247 000 |
Server 31.6 mln so'm (~2 675 $). Kamera boshiga oyiga ~298 ming so'm (GMC bilan) va ~247 ming so'm (GMCsiz). Ulushning 70% dan ko'prog'i — server, ya'ni sig'im: har qo'shimcha kamera server ulushini kamaytiradi. Elektr — 54 va 47 ming so'm; protsessor quvvati taxmin bo'lgani uchun bu eng noaniq qator. Kameraning o'zi — 25 ming so'm. Tannarxga ish kirmagan: o'rnatish, sozlash, qo'llab-quvvatlash — ularni o'z soatbay narxingiz bilan qo'shing (3-mashq). Litsenziya ham kirmagan: AGPL yo'lida u nol, Enterprise yo'lida — Ultralytics aytadigan narx, Apache modeliga o'tishda — qayta o'qitish ishi (23-bob).
Narx modellari
Tannarx — pastki chegara. Ustiga o'rnatish, qo'llab-quvvatlash ishi va foyda qo'shiladi. Uchta keng tarqalgan model:
- Bir martalik sotuv. Mijoz uskuna, o'rnatish va litsenziya uchun bir marta to'laydi, keyin yillik qo'llab-quvvatlash shartnomasi. Uskuna mijozniki, pul boshida keladi. Kod mijozga beriladi — 23-bobdagi AGPL masalasi aynan shu yerda.
- Oylik obuna (kamera boshiga). Uskuna bizniki, mijoz har oy to'laydi. Mijozga kirish oson, bizga — pul sekin qaytadi va uskunaning xavfi bizda.
- Aralash. Uskuna bir martalik, dastur va qo'llab-quvvatlash — oylik.
Obuna modelida asosiy savol: uskuna necha oyda qaytadi? 8 kamerali qurilish maydoni uchun, obuna narxi tannarxning bir necha baravari bo'lsa:
MAYDON = 8 for gmc, n in sigim.items(): serverlar = math.ceil(MAYDON / n) uskuna = serverlar * server + MAYDON * KAMERA elektr_oy = tannarx[gmc]["elektr"] * MAYDON satrlar = [] for k in (1.5, 2, 3): narx = tannarx[gmc]["jami"] * k satrlar.append({"narx / tannarx": k, "so'm / kamera / oy": round(narx, -3), "maydon, so'm / oy": round(narx * MAYDON, -3), "uskuna qaytadi, oy": round(uskuna / (narx * MAYDON - elektr_oy), 1)}) print(f"GMC={gmc}: {serverlar} server, uskuna {uskuna:,} so'm".replace(",", " ")) show(pd.DataFrame(satrlar))
GMC=sparseOptFlow: 2 server uskuna 70 294 000 so'm GMC=none: 2 server uskuna 70 294 000 so'm
| narx / tannarx | so'm / kamera / oy | maydon, so'm / oy | uskuna qaytadi, oy |
|---|---|---|---|
| 1.5 | 447 000 | 3 572 000 | 22.4 |
| 2 | 595 000 | 4 763 000 | 16.2 |
| 3 | 893 000 | 7 144 000 | 10.5 |
| narx / tannarx | so'm / kamera / oy | maydon, so'm / oy | uskuna qaytadi, oy |
|---|---|---|---|
| 1.5 | 370 000 | 2 961 000 | 27.2 |
| 2 | 494 000 | 3 948 000 | 19.7 |
| 3 | 740 000 | 5 923 000 | 12.7 |
Server butun son bo'lib sotiladi: 8 kamera uchun ikkala holatda ham 2 ta server kerak. GMCsiz holatda ikkinchi server to'liq band emas — kamera boshiga tannarx kichikroq, lekin maydon uchun uskuna bir xil, shuning uchun uskuna sekinroq qaytadi. Obuna tannarxning 1.5 baravari bo'lsa, uskuna 22–27 oyda qaytadi — 36 oylik muddatga yaqin: mijoz ikkinchi yili ketsa, zarar. 3 baravarida — 10.5–12.7 oyda. Qisqa loyiha (bitta qurilish — bir-ikki yil) uchun bir martalik yoki aralash model xavfsizroq; uzoq mijoz uchun — obuna.
Mijoz nima uchun to'laydi
Qonuniy majburiyat. 24-bobda ko'rdik: ish beruvchi himoya vositalarisiz xodimni ishdan chetlashtirishi shart (MK 151) va ish joyidagi sharoit ustidan nazorat qilishi shart (MK 359). O'sha 359-modda ish beruvchidan "mehnatni muhofaza qilish xizmatini ... tashkil etishi"ni ham talab qiladi — mijoz tomonida tizimdan foydalanuvchi va ko'pincha qaror qiluvchi aynan shu xizmat. Bu majburiyat faqat qurilishga emas, har bir ish beruvchiga tegishli: zavod, ombor, kon — bir xil mantiq.
Jarima. MJtK 49-moddasi: mansabdor shaxs tomonidan mehnat va mehnatni muhofaza qilish qonunchiligini buzish — BHM ning 5–10 baravari (2.2–4.4 mln so'm), bir yil ichida takrorlansa — 10–15 baravari (4.4–6.6 mln so'm). Taqqoslang: 8 kamerali maydon tannarxning 2 baravarida oyiga ~4.8 mln so'm. Lekin jarima faqat tekshiruvda chiqadi — narxni u bilan asoslash zaif. Asosiy qiymat — baxtsiz hodisaning oldini olish, uning narxini (davolash, ish to'xtashi, sud) esa mijozning o'zi biladi: pilotda so'rang va yozib oling.
Signal sifati. Mijoz kamera uchun emas, to'g'ri signal uchun to'laydi. 22-bobda tasdiqsiz tizim 20 soniyada 91 ta signal berdi — bunday tizim birinchi haftadayoq o'chiriladi. Tasdiq bilan — 6 ta. Shuning uchun narx pilot natijasiga bog'lanadi: qabul qilish mezonlari 26-bobda.
Asosiy fikr
- Tannarx vazifaga bog'liq: odam sanash uchun bitta kompyuter ~70 kamera (18-bob), kaska nazorati uchun — 4–5 ta.
- Bu kompyuterda cheklov — protsessor, GPU emas; kaska tekshiruvi kadr vaqtining yarmidan ko'pini oladi va kadrdagi odamlar soniga bog'liq.
- Kamera boshiga oylik tannarx ~250–300 ming so'm, uning 70% dan ko'prog'i — server. Sig'imni oshirish — tannarxni kamaytirishning asosiy yo'li.
- Serverlar butun son: maydonning kamera soni va server sig'imi mos kelmasa, uskuna sekin qaytadi.
- Narx modeli loyiha muddatiga mos bo'lsin: qisqa loyiha — bir martalik yoki aralash, uzoq mijoz — obuna.
Mashqlar
- Kaska tekshiruvi eng qimmat bosqich. Uni har kadrda emas, har bir trek uchun har 3-kadrda qiling va yuklama sinovini takrorlang. Sig'im va tannarx qancha o'zgaradi? 22-bobdagi signallar jadvali o'zgarmaganini tekshiring.
- Yuklama sinovini maqsadli serveringizda (butun protsessorli Linux yoki arzonroq GPU, masalan 8 GB li) o'tkazing va
SERVERnarxlarini almashtiring. GPU xotirasi nechta ishchiga yetadi? - Tannarxga ishni qo'shing: o'rnatish soatlari (bir marta) va oylik qo'llab-quvvatlash soatlari, o'z soatbay narxingiz bilan. 8 kamerali, 18 oylik qurilish loyihasi uchun uch modelning qaysi biri sizga va mijozga foydaliroq?
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.