File size: 5,744 Bytes
f68f2e8
bf0a759
f68f2e8
bf0a759
f68f2e8
 
bf0a759
 
f68f2e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf0a759
f68f2e8
bf0a759
f68f2e8
bf0a759
f68f2e8
 
 
bf0a759
f68f2e8
 
 
 
 
072cb0b
bf0a759
f68f2e8
 
 
 
 
 
 
072cb0b
f68f2e8
 
 
 
 
 
072cb0b
f68f2e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf0a759
f68f2e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf0a759
 
f68f2e8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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()