From 4ac2efa36d1a80c3b697bdca26da38b56906e81a Mon Sep 17 00:00:00 2001 From: gr1nd3lw4ld Date: Wed, 26 Jul 2023 23:24:11 +0530 Subject: [PATCH 1/5] updated gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8c42b28..5cbb1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,7 @@ captures/ .idea/dictionaries .idea/libraries .idea/caches - +.idea # Keystore files # Uncomment the following line if you do not want to check your keystore files in. #*.jks @@ -60,3 +60,6 @@ fastlane/Preview.html fastlane/screenshots fastlane/test_output fastlane/readme.md +.gitignore + +visionppi/.idea From 31f4b37dc7d7f3ca2868c4d92488b4e7179517c5 Mon Sep 17 00:00:00 2001 From: gr1nd3lw4ld Date: Wed, 26 Jul 2023 23:39:43 +0530 Subject: [PATCH 2/5] added data augmentation techniques --- DataCollection/GenerateImages.py | 316 +++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) diff --git a/DataCollection/GenerateImages.py b/DataCollection/GenerateImages.py index 9490164..b0fb864 100644 --- a/DataCollection/GenerateImages.py +++ b/DataCollection/GenerateImages.py @@ -11,6 +11,8 @@ import random import glob import cv2 +from scipy.ndimage.interpolation import map_coordinates +from scipy.ndimage.filters import gaussian_filter # Helper function to generate a mask for parallel light method def generate_parallel_light_mask(mask_size, @@ -122,6 +124,74 @@ def _decay_value_radically_norm(x, centers, max_value, min_value, dev): return x_value +def add_shadow(image, darkness_factor=0.5, x_offset=25, y_offset=25): + # Convert image to grayscale + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + # Apply a binary threshold to create a mask of the image + ret, mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) + # Blur the mask to create a softer shadow effect + mask_blur = cv2.GaussianBlur(mask, (21, 21), 0) + # Create a copy of the original image and apply the mask to it + shadow = np.copy(image) + shadow[mask_blur>0] = (shadow[mask_blur>0]*darkness_factor).astype(np.uint8) + # Shift the shadow image by the specified x and y offsets + M = np.float32([[1, 0, x_offset], [0, 1, y_offset]]) + shadow = cv2.warpAffine(shadow, M, (image.shape[1], image.shape[0])) + # Combine the original image and the shadow image using a bitwise OR operation + result = cv2.bitwise_or(image, shadow) + return result + +def add_glare(image, brightness_factor=0.5, x_offset=25, y_offset=25): + # Create a copy of the original image + glare = np.copy(image) + # Set the pixels in the top left corner of the image to white + glare[:100, :100, :] = [255, 255, 255] + # Blend the glare image with the original image using the specified brightness factor + glare = cv2.addWeighted(image, 1 - brightness_factor, glare, brightness_factor, 0) + # Shift the glare image by the specified x and y offsets + M = np.float32([[1, 0, x_offset], [0, 1, y_offset]]) + glare = cv2.warpAffine(glare, M, (image.shape[1], image.shape[0])) + # Combine the original image and the glare image using a bitwise OR operation + result = cv2.bitwise_or(image, glare) + return result + +def add_fog(image, brightness=50, density=0.5): + # Convert the image to grayscale + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + # Generate a mask with random noise + mask = np.zeros_like(gray) + h, w = mask.shape[:2] + noise = cv2.randu(mask, 0, 255) + mask = cv2.GaussianBlur(mask, (51, 51), 0) + mask = cv2.threshold(mask, 240, 255, cv2.THRESH_BINARY)[1] + # Blend the mask with the original image + mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) + mask = np.float32(mask) / 255.0 + result = ((1.0 - density) * image + density * (brightness * mask)) + result = np.clip(result, 0, 255) + result = np.uint8(result) + return result + +def add_speckle_noise(image, mean=0, std=50): + # Generate random noise + h, w, c = image.shape + noise = np.random.normal(mean, std, size=(h, w, c)) + # Add noise to the image + noisy_image = image + image * noise / 255.0 + noisy_image = np.clip(noisy_image, 0, 255).astype(np.uint8) + return noisy_image + +def apply_local_distortion(image, distortion_intensity=0.5): + # Generate random noise with the same shape as the image + noise = np.random.normal(scale=distortion_intensity, size=image.shape) + # Add the noise to the image + distorted_image = image + noise + # Clip the pixel values to [0, 255] range + distorted_image = np.clip(distorted_image, 0, 255) + # Convert the image to uint8 format + distorted_image = distorted_image.astype(np.uint8) + return distorted_image + # Allowing users to give input as command line arguments ap = argparse.ArgumentParser() @@ -406,3 +476,249 @@ def _decay_value_radically_norm(x, centers, max_value, min_value, dev): savePath = output + str(i) + ".png" i += 1 cv2.imwrite(savePath, frame) + + # Augmentation by scaling images + height, width = image.shape[:2] + + # Scale the image by a factor of 0.5 + scale = 0.5 + resized = cv2.resize(image, (int(width*scale), int(height*scale))) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, resized) + + # Scale the image by a factor of 1.5 + scale = 1.5 + resized = cv2.resize(image, (int(width*scale), int(height*scale))) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, resized) + + # Scale the image by a factor of 2 + scale = 2 + resized = cv2.resize(image, (int(width*scale), int(height*scale))) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, resized) + + # Augmentation by color channel swapping + # Swap Red and Blue channels + swapped = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, swapped) + + # Swap Green and Blue channels + swapped = image[:, :, ::-1] + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, swapped) + + # Swap Red and Green channels + swapped = image[:, ::-1, :] + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, swapped) + + # Augmentation by adding random noise and blurring + # Add Gaussian noise to the image + mean = 0 + variance = 50 + noise = np.random.normal(mean, variance, image.shape) + noisy_image = np.clip(image + noise, 0, 255).astype(np.uint8) + + # Apply Gaussian blur to the noisy image + ksize = (5, 5) + sigmaX = 5 + blurred = cv2.GaussianBlur(noisy_image, ksize, sigmaX) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, blurred) + + # Add Salt-and-Pepper noise to the image + s_vs_p = 0.5 + amount = 0.05 + noisy_image = image.copy() + # Salt mode + num_salt = np.ceil(amount * image.size * s_vs_p) + coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape] + noisy_image[coords] = 255 + + # Pepper mode + num_pepper = np.ceil(amount * image.size * (1. - s_vs_p)) + coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape] + noisy_image[coords] = 0 + + # Apply Median blur to the noisy image + ksize = 5 + blurred = cv2.medianBlur(noisy_image, ksize) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, blurred) + + # Augmentation by randomly rotating and zooming + # Randomly rotate the image by a random angle between -10 and 10 degrees + angle = np.random.uniform(-10, 10) + rotated = ndimage.rotate(image, angle, reshape=False) + + # Randomly zoom the rotated image by a random factor between 0.9 and 1.1 + zoom_factor = np.random.uniform(0.9, 1.1) + zoomed = ndimage.zoom(rotated, zoom_factor) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, zoomed) + + # Augmentation by randomly dropping color channels + channels = cv2.split(image) + num_channels = len(channels) + + # Randomly drop one or more color channels + num_dropped = np.random.randint(1, num_channels + 1) + dropped_channels = np.random.choice(num_channels, num_dropped, replace=False) + for j in dropped_channels: + channels[j][:] = 0 + + # Merge the remaining channels + merged = cv2.merge(channels) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, merged) + + # Augmentation by cutout with random erasing + height, width, channels = image.shape + + # Define the size and position of the cutout + cutout_size = int(min(height, width) * 0.2) # Cutout size is 20% of the smaller dimension + cutout_x = np.random.randint(0, width - cutout_size + 1) + cutout_y = np.random.randint(0, height - cutout_size + 1) + + # Apply cutout to the image + cutout_image = np.copy(image) + cutout_image[cutout_y:cutout_y+cutout_size, cutout_x:cutout_x+cutout_size, :] = 0 + + # Define the size and position of the random erasing + erase_size = int(min(height, width) * 0.1) # Erase size is 10% of the smaller dimension + erase_x = np.random.randint(0, width - erase_size + 1) + erase_y = np.random.randint(0, height - erase_size + 1) + + # Apply random erasing to the image + erase_image = np.copy(cutout_image) + erase_image[erase_y:erase_y+erase_size, erase_x:erase_x+erase_size, :] = np.random.randint(0, 256, (erase_size, erase_size, channels)) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, erase_image) + + # Augmentation by geometric transformations + height, width, channels = image.shape + + # Skew transformation + skew_x = np.random.randint(-int(width * 0.1), int(width * 0.1)) + skew_y = np.random.randint(-int(height * 0.1), int(height * 0.1)) + pts1 = np.float32([[0, 0], [width, 0], [0, height], [width, height]]) + pts2 = np.float32([[0, 0], [width, 0], [skew_x, height+skew_y], [width+skew_x, height+skew_y]]) + M = cv2.getPerspectiveTransform(pts1, pts2) + skew_image = cv2.warpPerspective(image, M, (width, height)) + + # Stretch transformation + stretch_x = np.random.uniform(0.8, 1.2) + stretch_y = np.random.uniform(0.8, 1.2) + stretch_image = cv2.resize(image, (int(width*stretch_x), int(height*stretch_y))) + + # Twist transformation + twist_x = np.random.randint(-int(width * 0.1), int(width * 0.1)) + twist_y = np.random.randint(-int(height * 0.1), int(height * 0.1)) + M = cv2.getRotationMatrix2D((width/2, height/2), 15, 1) + M[0][2] += twist_x + M[1][2] += twist_y + twist_image = cv2.warpAffine(image, M, (width, height)) + + # Save the transformed images + savePath = output + str(i) + "_skew.png" + cv2.imwrite(savePath, skew_image) + i += 1 + savePath = output + str(i) + "_stretch.png" + cv2.imwrite(savePath, stretch_image) + i += 1 + savePath = output + str(i) + "_twist.png" + cv2.imwrite(savePath, twist_image) + i += 1 + + # Augmentation by local pixelization + height, width, channels = image.shape + pixel_size = int(min(height, width) * 0.1) # Size of each pixel is 10% of the smaller dimension + for y in range(0, height, pixel_size): + for x in range(0, width, pixel_size): + image[y:y+pixel_size, x:x+pixel_size, :] = np.mean(image[y:y+pixel_size, x:x+pixel_size, :], axis=(0,1), keepdims=True) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, image) + + + # Shadow Effect + shadow_image = add_shadow(image, darkness_factor=0.7, x_offset=50, y_offset=50) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, shadow_image) + + # Glare Effect + glare_image = add_glare(image, brightness_factor=0.7, x_offset=50, y_offset=50) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, glare_image) + + # Fog Effect + fog_image = add_fog(image, brightness=80, density=0.6) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, fog_image) + + # Speckle Noise + noisy_image = add_speckle_noise(image, mean=0, std=50) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, noisy_image) + + # Local Distortion + distorted_image = apply_local_distortion(image, distortion_intensity=0.5) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, distorted_image) + + # Applying the Patch Gaussian augmentation + augmented_image = image.copy() + rows, cols, channels = augmented_image.shape + for _ in range(5): + # Generate random patch + patch_size = np.random.randint(20, 50) + x = np.random.randint(0, cols - patch_size) + y = np.random.randint(0, rows - patch_size) + patch = augmented_image[y:y+patch_size, x:x+patch_size].copy() + + # Apply Gaussian blur to patch + patch = cv2.GaussianBlur(patch, (15, 15), 0) + + # Blend patch into original image + alpha = np.random.uniform(0.3, 0.7) + augmented_image[y:y+patch_size, x:x+patch_size] = cv2.addWeighted(patch, alpha, augmented_image[y:y+patch_size, x:x+patch_size], 1-alpha, 0) + + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, augmented_image) + + # Perspective cropping + height, width = image.shape[:2] + pts1 = np.float32([[0, 0], [width, 0], [0, height], [width, height]]) + pt1 = 0.15*width + pt2 = 0.85*width + pts2 = np.float32([[pt1, 0], [pt2, 0], [0, height], [width, height]]) + M = cv2.getPerspectiveTransform(pts1, pts2) + perspective = cv2.warpPerspective(image, M, (width, height)) + savePath = output + str(i) + ".png" + i += 1 + cv2.imwrite(savePath, perspective) \ No newline at end of file From 47ac0b77623978b91c82c7cc9c64176f2de526e3 Mon Sep 17 00:00:00 2001 From: gr1nd3lw4ld Date: Wed, 26 Jul 2023 23:46:02 +0530 Subject: [PATCH 3/5] new ui --- visionppi/.idea/gradle.xml | 2 +- visionppi/.idea/misc.xml | 21 ++ visionppi/app/build.gradle | 39 ++- visionppi/app/src/main/AndroidManifest.xml | 19 +- .../java/org/mifos/visionppi/MainActivity.kt | 8 +- .../java/org/mifos/visionppi/VisionPPI.kt | 6 +- .../visionppi/adapters/ClientSearchAdapter.kt | 19 +- .../adapters/ObjectDetectionResultAdapter.kt | 15 +- .../visionppi/adapters/QuestionAdapter.kt | 14 +- .../visionppi/adapters/ResponseAdapter.kt | 13 +- .../adapters/SelectedImageAdapter.kt | 14 +- .../java/org/mifos/visionppi/models/User.kt | 4 +- .../visionppi/models/mifoserror/Errors.kt | 25 +- .../org/mifos/visionppi/objects/Client.kt | 35 +- .../org/mifos/visionppi/ui/AboutActivity.kt | 6 +- .../visionppi/ui/activities/LoginActivity.kt | 24 +- .../client_profile/ClientProfileActivity.kt | 37 +-- .../computer_vision/ComputerVisionActivity.kt | 39 ++- .../mifos/visionppi/ui/home/MainActivity.kt | 34 +- .../mifos/visionppi/ui/menu/MenuActivity.kt | 108 ++++++ .../mifos/visionppi/ui/menu/MenuMVPView.kt | 8 + .../mifos/visionppi/ui/menu/MenuPresenter.kt | 21 ++ .../ui/new_survey/NewSurveyActivity.kt | 21 +- .../ui/new_survey/PPIQuestionFragment.kt | 22 +- .../ui/user_profile/UserProfileActivity.kt | 53 ++- .../java/org/mifos/visionppi/utils/AuthKey.kt | 1 + .../java/org/mifos/visionppi/utils/Network.kt | 2 +- .../res/drawable/ic_baseline_analytics_24.xml | 5 + .../main/res/drawable/ic_baseline_menu_24.xml | 5 + .../res/drawable/ic_baseline_search_24.xml | 5 + .../src/main/res/layout/activity_about.xml | 4 +- .../src/main/res/layout/activity_login.xml | 3 +- .../app/src/main/res/layout/activity_main.xml | 27 ++ .../src/main/res/layout/activity_main2.xml | 6 +- .../app/src/main/res/layout/activity_menu.xml | 307 ++++++++++++++++++ .../main/res/layout/activity_new_survey.xml | 1 + .../res/layout/activity_ppi_view_pager.xml | 4 +- .../main/res/layout/activity_user_profile.xml | 38 ++- .../src/main/res/layout/image_grid_layout.xml | 3 +- .../main/res/layout/new_survey_toolbar.xml | 1 + .../src/main/res/layout/ppi_response_row.xml | 3 +- .../app/src/main/res/menu/bottom_nav_menu.xml | 13 +- .../main/res/navigation/mobile_navigation.xml | 12 +- visionppi/app/src/main/res/values/strings.xml | 3 + visionppi/build.gradle | 9 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 46 files changed, 844 insertions(+), 217 deletions(-) create mode 100644 visionppi/app/src/main/java/org/mifos/visionppi/ui/menu/MenuActivity.kt create mode 100644 visionppi/app/src/main/java/org/mifos/visionppi/ui/menu/MenuMVPView.kt create mode 100644 visionppi/app/src/main/java/org/mifos/visionppi/ui/menu/MenuPresenter.kt create mode 100644 visionppi/app/src/main/res/drawable/ic_baseline_analytics_24.xml create mode 100644 visionppi/app/src/main/res/drawable/ic_baseline_menu_24.xml create mode 100644 visionppi/app/src/main/res/drawable/ic_baseline_search_24.xml create mode 100644 visionppi/app/src/main/res/layout/activity_main.xml create mode 100644 visionppi/app/src/main/res/layout/activity_menu.xml diff --git a/visionppi/.idea/gradle.xml b/visionppi/.idea/gradle.xml index 3a6d748..6e5389e 100644 --- a/visionppi/.idea/gradle.xml +++ b/visionppi/.idea/gradle.xml @@ -7,7 +7,7 @@