import cv2 import numpy as np import gradio as gr class CameraAnalyzerState: def __init__(self): self.accumulated_frame = None self.frame_count = 0 self.mode = "LIVE" # LIVE, DARK_CALIB, FLAT_CALIB, SPN_VIEW self.hot_pixels = [] self.dead_pixels = [] self.msg = "Hazır. Canlı mod." def reset(self): self.accumulated_frame = None self.frame_count = 0 self.mode = "LIVE" self.msg = "Sıfırlandı." # Global state (Tek kullanıcı demo için. Çoklu kullanıcı için gr.State kullanılmalı ama basitlik adına global tutuyoruz) analyzer = CameraAnalyzerState() def process_frame(frame): global analyzer if frame is None: return None # Görüntüyü çevir (Mirror effect) frame = cv2.flip(frame, 1) display_frame = frame.copy() # Griye çevir (işlemler için) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY).astype(np.float32) # --- DURUM YÖNETİMİ --- if analyzer.mode == "DARK_CALIB" or analyzer.mode == "FLAT_CALIB": if analyzer.accumulated_frame is None: analyzer.accumulated_frame = gray else: cv2.accumulateWeighted(gray, analyzer.accumulated_frame, 0.1) analyzer.frame_count += 1 # 30 kare toplandıysa analizi yap if analyzer.frame_count > 30: avg_frame = cv2.convertScaleAbs(analyzer.accumulated_frame) if analyzer.mode == "DARK_CALIB": # Hot Pixel Analizi _, thresh = cv2.threshold(avg_frame, 25, 255, cv2.THRESH_BINARY) coords = cv2.findNonZero(thresh) analyzer.hot_pixels = [(p[0][0], p[0][1]) for p in coords] if coords is not None else [] analyzer.msg = f"Karanlik Kalibrasyon Bitti! {len(analyzer.hot_pixels)} sicak piksel bulundu." elif analyzer.mode == "FLAT_CALIB": # Dead Pixel Analizi mean_val = np.mean(avg_frame) threshold_val = mean_val * 0.6 _, thresh = cv2.threshold(avg_frame, threshold_val, 255, cv2.THRESH_BINARY_INV) coords = cv2.findNonZero(thresh) analyzer.dead_pixels = [(p[0][0], p[0][1]) for p in coords] if coords is not None else [] analyzer.msg = f"Duz Alan Kalibrasyonu Bitti! {len(analyzer.dead_pixels)} olu piksel bulundu." # Analiz bitince Live moda dön ama verileri sakla analyzer.mode = "LIVE" analyzer.accumulated_frame = None analyzer.frame_count = 0 else: analyzer.msg = f"Kalibrasyon yapiliyor... {analyzer.frame_count}/30" # --- GÖRSELLEŞTİRME --- # SPN Modu (Gürültü Görme) if analyzer.mode == "SPN_VIEW": # SPN için anlık kareyi yumuşatıp çıkarıyoruz (basitleştirilmiş anlık SPN) # Gerçek SPN birikmiş kare ister ama webcam akışında anlık göstermek daha efektiftir float_img = gray denoised = cv2.GaussianBlur(float_img, (5, 5), 0) residue = float_img - denoised spn_vis = cv2.normalize(residue, None, 0, 255, cv2.NORM_MINMAX) spn_vis = cv2.convertScaleAbs(spn_vis, alpha=5.0, beta=128) display_frame = cv2.cvtColor(spn_vis, cv2.COLOR_GRAY2BGR) cv2.putText(display_frame, "SPN MODU", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2) # İşaretlemeler (Live Modda) else: # Hot Pixels (Kırmızı) for x, y in analyzer.hot_pixels: cv2.circle(display_frame, (x, y), 8, (255, 0, 0), 2) # Kırmızı (RGB'de Gradio BGR alabilir dikkat) # Dead Pixels (Mavi) for x, y in analyzer.dead_pixels: cv2.circle(display_frame, (x, y), 8, (0, 0, 255), 2) # Mavi # Bilgi mesajı cv2.putText(display_frame, analyzer.msg, (10, display_frame.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # OpenCV BGR formatından RGB formatına çevir (Gradio için) return cv2.cvtColor(display_frame, cv2.COLOR_BGR2RGB) def set_mode_dark(): analyzer.mode = "DARK_CALIB" analyzer.accumulated_frame = None analyzer.frame_count = 0 analyzer.msg = "Lensi kapatin..." return def set_mode_flat(): analyzer.mode = "FLAT_CALIB" analyzer.accumulated_frame = None analyzer.frame_count = 0 analyzer.msg = "Beyaz bir duvara tutun..." return def set_mode_spn(): analyzer.mode = "SPN_VIEW" analyzer.msg = "SPN Modu" return def reset_all(): analyzer.reset() return # --- ARAYÜZ --- with gr.Blocks() as demo: gr.Markdown("# Kamera Dead Pixel & SPN Analizi") gr.Markdown("Bu araç tarayıcı kameranızı kullanarak sensör analizi yapar.") with gr.Row(): start_dark = gr.Button("1. Karanlık Kalibrasyon (Hot Pixel)") start_flat = gr.Button("2. Düz Alan Kalibrasyon (Dead Pixel)") start_spn = gr.Button("3. SPN Modu (Gürültü)") btn_reset = gr.Button("Sıfırla") # Webcam Input (Streaming=True sürekli akış sağlar) image_input = gr.Image(sources=["webcam"], streaming=True, label="Kamera") image_output = gr.Image(label="Analiz Sonucu") # Buton olayları start_dark.click(fn=set_mode_dark, inputs=None, outputs=None) start_flat.click(fn=set_mode_flat, inputs=None, outputs=None) start_spn.click(fn=set_mode_spn, inputs=None, outputs=None) btn_reset.click(fn=reset_all, inputs=None, outputs=None) # Akış döngüsü image_input.stream(fn=process_frame, inputs=image_input, outputs=image_output, time_limit=600) if __name__ == "__main__": demo.launch()