diff --git a/bird_cnn/r-cnn.py b/bird_cnn/r-cnn.py new file mode 100644 index 0000000..22792a1 --- /dev/null +++ b/bird_cnn/r-cnn.py @@ -0,0 +1,51 @@ +import torch +import torch.nn as nn +import torchvision +from torchvision import datasets, transforms +from torch.utils.data import DataLoader, random_split +import matplotlib.pyplot as plt + +from bird_cnn import Bird_CNN, sample, trainCNN + +from enum import Enum + +from PIL import Image + +SAVE_PATH = "./saved_models" +IMAGE_SIZE = 64 + +class bird_species(Enum): + Common_Kingfisher = 0 + CommonMyna = 1 + House_Crow = 2 + Indian_Peacock = 3 + Indian_Pitta = 4 + Ruddy_Shelduck = 5 + Sarus_Crane = 6 + +transform = transforms.Compose([ + transforms.Resize(IMAGE_SIZE), + transforms.CenterCrop(IMAGE_SIZE), + transforms.ToTensor() +]) + +dataset = datasets.ImageFolder("data/train", transform=transform) + +train_size = int(0.8 * len(dataset)) +val_size = len(dataset) - train_size + +train_dataset, val_dataset = random_split(dataset, [train_size, val_size]) + +train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) +val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False) + + +device = torch.device("cpu") if not torch.cuda.is_available() else torch.device("cuda:0") +print("Using device", device) + +model = Bird_CNN(c_in=3, c_hidden=32, c_out=7) +model.to(device) +optimizer = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-4) +loss_module = nn.CrossEntropyLoss() + +trainCNN(model, optimizer, loss_module, train_loader, val_loader, device, 50, SAVE_PATH=SAVE_PATH, save=True) \ No newline at end of file diff --git a/bird_cnn/selective_search.py b/bird_cnn/selective_search.py new file mode 100644 index 0000000..a6339e4 --- /dev/null +++ b/bird_cnn/selective_search.py @@ -0,0 +1,85 @@ +from collections import defaultdict +from enum import Enum +import os + +import numpy as np +import matplotlib.pyplot as plt +import cv2 + +import torch +from torchvision import transforms +import torch.nn.functional as F + +from bird_cnn import Bird_CNN + +from PIL import Image + + + +BUILD_PATH = "./build_models" +IMAGE_SIZE = 64 + +class bird_species(Enum): + Common_Kingfisher = 0 + CommonMyna = 1 + House_Crow = 2 + Indian_Peacock = 3 + Indian_Pitta = 4 + Ruddy_Shelduck = 5 + Sarus_Crane = 6 + +transform = transforms.Compose([ + transforms.Resize(IMAGE_SIZE), + transforms.CenterCrop(IMAGE_SIZE), + transforms.ToTensor() +]) + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +model = Bird_CNN(c_in=3, c_hidden=16, c_out=7) +full_path = os.path.join(BUILD_PATH, "bird_cnn") +model.load_state_dict(torch.load(full_path, map_location=torch.device(device))) +model.to(device) +model.eval() + +img = cv2.imread("./testimages/two_crows.jpg") + +if img is None: + raise ValueError("Image not found or path is wrong") + +ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation() +ss.setBaseImage(img) + +ss.switchToSelectiveSearchFast() +rects = ss.process() + +# convert to array for easy sorting +rects = np.array(rects) + +# compute area +areas = rects[:, 2] * rects[:, 3] + +# sort by area (descending) +idx = np.argsort(-areas) + +# take top 10 +top10 = rects[idx[:200]] +class_conf_sum = defaultdict(float) + +for (x, y, w, h) in top10: + #cv2.rectangle(img_copy, (x, y), (x + w, y + h), (0, 255, 0), 1) + crop = img[y:y+h, x:x+w] + crop_pil = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)) + image = transform(crop_pil).unsqueeze(0).to(device) + + with torch.no_grad(): + pred = model(image) + probs = F.softmax(pred, dim=1) + confidence, cls = torch.max(probs, dim=1) + if confidence.item() < 0.7: + continue + + class_conf_sum[cls.item()] += confidence.item() + +for i in range(6): + print(str(i) + ": " + str(class_conf_sum[i])) diff --git a/bird_cnn/testimages/two_crows.jpg b/bird_cnn/testimages/two_crows.jpg new file mode 100644 index 0000000..b734da0 Binary files /dev/null and b/bird_cnn/testimages/two_crows.jpg differ diff --git a/cnn_website/src/Bird_CNN.css b/cnn_website/src/Bird_CNN.css index 2186d8e..e806463 100644 --- a/cnn_website/src/Bird_CNN.css +++ b/cnn_website/src/Bird_CNN.css @@ -1,3 +1,7 @@ +.button-div { + height: 40px; +} + .custom-button { font-size: 1rem; font-weight: bold; @@ -27,11 +31,10 @@ } #site-headline { - margin-left: 100px; - margin-bottom: 50px; + margin: 50px min(100px, 10vw) 50px min(100px, 10vw); color: rgb(47, 168, 208); font-weight: bold; - font-size: 4rem; + font-size: clamp(1rem, 8vw, 4rem); position: relative; width: fit-content; } @@ -67,12 +70,13 @@ a:hover { flex-wrap: wrap; overflow: hidden; border-radius: 12px; - margin: 180px 50px 50px 50px; + margin: 50px 50px 50px 50px; } .image-box { - height: 400px; + height: fit-content; margin-top: 40px; + margin-bottom: 40px; display: flex; align-items: center; justify-content: center; @@ -86,7 +90,10 @@ a:hover { cursor: pointer; border: 2px solid black; border-Radius: 10px; - + user-select: none; + height: auto; + max-height: 400px; + max-width: min(700px, 80vw); } .image-box img:hover { @@ -95,15 +102,27 @@ a:hover { .content-block { display: flex; + justify-content: center; align-items: center; - gap: 20px; - height: 40px; + flex-wrap: wrap; + column-gap: 20px; + height: fit-content; + width: fit-content; +} + +.loader-container { + scroll-margin-top: 100px; + width: 85px; + height: 35px; + display: flex; + justify-content: center; + padding: 20px 0px 20px 0px; } /* HTML:
*/ .loader { - width: 85px; - height: 25px; + width: 100%; + height: 100%; --g1: conic-gradient(from 90deg at left 3px top 3px, #0000 90deg, #fff 0); --g2: conic-gradient(from -90deg at bottom 3px right 3px, #0000 90deg, #fff 0); background: var(--g1), var(--g1), var(--g1), var(--g2), var(--g2), var(--g2); @@ -136,4 +155,52 @@ a:hover { 100% { background-size: 25px 100%, 25px 100%, 25px 100% } +} + +.site-box { + margin-top: 150px; + width: 100%; +} + +.request-box { + height: fit-content; + width: min(700px, 80%); + display: flex; + flex-direction: column; + align-items: center; + flex: 0 0 auto; + margin: 0px 50px 0px 50px; +} + +.request-box * { + box-sizing: content-box; +} + +.input-box { + scroll-margin-top: 100px; + width: min(500px, 100%); + height: 160px; + display: flex; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; + gap: 20px; +} + +.response-block { + width: 80%; + height: 100px; + margin: 40px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + gap: 40px; +} + +.conten-block-text { + display: flex; + flex-direction: column; + justify-content: center; + margin: 0; } \ No newline at end of file diff --git a/cnn_website/src/Bird_CNN.jsx b/cnn_website/src/Bird_CNN.jsx index 2bbdf8e..e0d234b 100644 --- a/cnn_website/src/Bird_CNN.jsx +++ b/cnn_website/src/Bird_CNN.jsx @@ -85,7 +85,7 @@ function Bird_CNN() { return ( <> -{birdClass}
+{birdClass}
{confidence}
+{confidence}