File size: 4,627 Bytes
b730b20
 
 
 
 
 
 
 
96b923d
 
 
b730b20
96b923d
 
b730b20
96b923d
 
b730b20
 
96b923d
 
b730b20
96b923d
b730b20
 
96b923d
 
 
 
 
 
 
b730b20
 
 
96b923d
b730b20
 
96b923d
b730b20
 
 
96b923d
 
 
 
b730b20
 
 
96b923d
 
 
 
 
 
 
 
 
 
 
 
b730b20
 
96b923d
 
b730b20
 
96b923d
b730b20
 
 
 
 
96b923d
 
 
 
b730b20
 
96b923d
b730b20
 
 
 
 
96b923d
 
 
 
b730b20
 
96b923d
 
 
 
b730b20
96b923d
 
 
 
 
 
 
b730b20
 
96b923d
 
 
b730b20
 
 
96b923d
 
b730b20
96b923d
 
 
b730b20
96b923d
 
 
 
b730b20
96b923d
 
 
 
 
 
 
 
 
b730b20
 
 
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
import os
import cv2
import random
import numpy as np
from glob import glob
from tqdm import tqdm

# ================= CONFIGURATION =================
# 1. PATHS (Separated)
IMAGES_DIR = r"C:\Users\charu\Desktop\04-02-2026\images"
LABELS_DIR = r"C:\Users\charu\Desktop\04-02-2026\labels"

# 2. Target Count per class
TARGET_PER_CLASS = 300

# 3. Class Names
CLASS_NAMES = {0: "Blast", 1: "Brown Spot", 2: "Sheath Blight"}
# =================================================

def load_dataset():
    dataset = {0: [], 1: [], 2: []}
    
    # scan labels folder
    txt_files = glob(os.path.join(LABELS_DIR, "*.txt"))
    
    print(f"๐Ÿ“‚ Scanning Labels: {LABELS_DIR}")
    print(f"   -> Found {len(txt_files)} text files.")
    
    if len(txt_files) == 0:
        print(" Error: No text files found! Check the path.")
        return dataset

    for txt_path in txt_files:
        filename = os.path.basename(txt_path).replace('.txt', '')
        
        # Look for matching image in IMAGES_DIR
        img_jpg = os.path.join(IMAGES_DIR, filename + ".jpg")
        img_png = os.path.join(IMAGES_DIR, filename + ".png")
        img_jpeg = os.path.join(IMAGES_DIR, filename + ".jpeg")
        
        if os.path.exists(img_jpg): img_path = img_jpg
        elif os.path.exists(img_png): img_path = img_png
        elif os.path.exists(img_jpeg): img_path = img_jpeg
        else: 
            # If no image found for this label, skip it
            continue 

        with open(txt_path, 'r') as f:
            lines = f.readlines()
            
        if lines:
            try:
                # Read class ID
                class_id = int(lines[0].split()[0])
                if class_id in dataset:
                    dataset[class_id].append((img_path, lines))
            except:
                pass 
    return dataset

def augment_polygon(img_path, lines, new_filename):
    img = cv2.imread(img_path)
    if img is None: return
    
    action = random.choice(["h_flip", "v_flip", "bright", "noise"])
    new_lines = []
    
    if action == "h_flip":
        new_img = cv2.flip(img, 1)
        for line in lines:
            parts = line.strip().split()
            cls = parts[0]
            coords = [float(x) for x in parts[1:]]
            new_coords = []
            for i, val in enumerate(coords):
                if i % 2 == 0: new_coords.append(1.0 - val) # X
                else:          new_coords.append(val)       # Y
            new_lines.append(f"{cls} " + " ".join([f"{c:.6f}" for c in new_coords]) + "\n")

    elif action == "v_flip":
        new_img = cv2.flip(img, 0)
        for line in lines:
            parts = line.strip().split()
            cls = parts[0]
            coords = [float(x) for x in parts[1:]]
            new_coords = []
            for i, val in enumerate(coords):
                if i % 2 == 0: new_coords.append(val)       # X
                else:          new_coords.append(1.0 - val) # Y
            new_lines.append(f"{cls} " + " ".join([f"{c:.6f}" for c in new_coords]) + "\n")

    elif action == "bright":
        beta = random.randint(-30, 30)
        new_img = cv2.convertScaleAbs(img, alpha=1.0, beta=beta)
        new_lines = lines 

    elif action == "noise":
        noise = np.random.normal(0, 15, img.shape).astype(np.uint8)
        new_img = cv2.add(img, noise)
        new_lines = lines 
        
    else: 
        new_img = img
        new_lines = lines

    # SAVE TO SEPARATE FOLDERS
    cv2.imwrite(os.path.join(IMAGES_DIR, new_filename + ".jpg"), new_img)
    with open(os.path.join(LABELS_DIR, new_filename + ".txt"), 'w') as f:
        f.writelines(new_lines)

def main():
    print("๐Ÿš€ Loading Dataset (Separated Folders)...")
    data_map = load_dataset()
    
    print("\n๐Ÿ“Š Current Counts:")
    for cid in [0, 1, 2]:
        print(f"   - {CLASS_NAMES[cid]}: {len(data_map[cid])} images")
        
    print("\n๐Ÿ› ๏ธ augmenting...")
    for cid in [0, 1, 2]:
        items = data_map[cid]
        needed = TARGET_PER_CLASS - len(items)
        
        if needed > 0 and items:
            print(f"   -> Generating {needed} images for {CLASS_NAMES[cid]}...")
            for i in tqdm(range(needed)):
                src_img, src_lines = random.choice(items)
                augment_polygon(src_img, src_lines, f"aug_{cid}_{i}")
        elif not items:
            print(f"โš ๏ธ Warning: No images found for {CLASS_NAMES[cid]}!")

    print("\nโœ… Done!")

if __name__ == "__main__":
    main()