File size: 5,305 Bytes
7890f1f
 
 
 
 
b08d464
7890f1f
e92ae0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cce947a
e92ae0e
 
cce947a
 
e92ae0e
cce947a
e92ae0e
 
 
ce5f33e
e92ae0e
 
 
 
cce947a
 
e92ae0e
 
 
cce947a
e92ae0e
cce947a
 
 
 
 
 
e92ae0e
 
 
 
cce947a
 
e92ae0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cce947a
e92ae0e
 
 
 
 
 
cce947a
e92ae0e
 
fe9ab56
 
 
e92ae0e
 
cce947a
 
 
e92ae0e
cce947a
e92ae0e
cce947a
e92ae0e
cce947a
e92ae0e
 
 
cce947a
e92ae0e
 
 
cce947a
e92ae0e
 
 
 
 
 
 
 
 
 
 
 
ce5f33e
e92ae0e
 
 
 
cce947a
e92ae0e
ce5f33e
cce947a
e92ae0e
 
 
cce947a
b08d464
 
 
cce947a
b08d464
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
import cv2
import numpy as np
import random
import os
from PIL import Image
from imageComparison import ImageComparison

class ImageProcessor:
    def __init__(self):
        pass

    def preprocess_image(self, image, grid_size):
        """
        Preprocess the uploaded image:
        1. Convert to RGB format if needed.
        2. Resize to a fixed resolution for consistent processing.
        """
        image = np.array(image)
        
        # Ensure the image is in RGB format
        if image.shape[-1] == 4:  # Handle images with alpha channel
            image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
        elif len(image.shape) == 2:  # Handle grayscale images
            image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)

        h, w = image.shape[:2]

        
        # Round down to nearest multiple of grid_size
        h = h - (h % grid_size)
        w = w - (w % grid_size)
        print(f"h: {h}, w: {w}")
        # Resize to a fixed size keep aspect ratio  
        resized_image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)
        
        return resized_image

    def divide_and_analyze_grid(self, image, grid_size):
        """
        Divide the image into a grid and classify each grid cell by average intensity or dominant color.
        Args:
            image: Preprocessed image (numpy array).
            grid_size: Size of the Tile cells (e.g., 8x8 or 16x16).
            keep_image_size: If True, keep the original image size.
        Returns:
            Annotated image with grid division and analysis results.
        """

        height, width, _ = image.shape
        new_height = height // grid_size
        new_width = width // grid_size
        cell_height = grid_size
        cell_width = grid_size

        print(cell_height, cell_width, grid_size, height, width)
        # Create a copy of the image for annotation
        annotated_image = image.copy()
        
        # Analyze each grid cell
        for row in range(new_height):
            for col in range(new_width):
                # Extract the grid cell
                col_start = col * cell_width
                col_end = col_start + cell_width
                row_start = row * cell_height
                row_end = row_start + cell_height
                grid_cell = image[row_start:row_end, col_start:col_end]

                # Calculate the average color
                avg_color = np.mean(grid_cell, axis=(0, 1)).astype(int)

                # i need integer values
                avg_color = (int(avg_color[0]), int(avg_color[1]), int(avg_color[2]))
                
                cv2.rectangle(
                    annotated_image, (col_start, row_start), (col_end, row_end), avg_color, -1
                )

       
        return Image.fromarray(annotated_image)

    def blend_tile_with_pixel(self, tile, color):
        """Blend a 32x32 tile with a given color."""
        color_layer = np.full_like(tile, color, dtype=np.uint8)  # Create a solid color layer
        blended_tile = cv2.addWeighted(tile, 0.3, color_layer, 0.7, 0)  
        return blended_tile 

    def add_tile_mapping(self, image, grid_size, tile_type):
        """
        Add tile mapping to the image.
        """
        robot_images = random.sample(os.listdir('public/' + tile_type), 10)
        image = np.array(image)
        image_height, image_width, _ = image.shape
        h, w = image_height // grid_size, image_width // grid_size

        # This comes from the array of robot images
        tile_h , tile_w = grid_size, grid_size
        
        mosaic = image.copy()
        
        print(f"h Final: {h}, w Final: {w}")
        # Iterate over each pixel in the base image
        for i in range(h):
            for j in range(w):
                pixel_color = image[i * grid_size, j * grid_size]  # Get the pixel color
                
                random_robot_image = random.choice(robot_images)
                robotina = cv2.imread(os.path.join('public/' + tile_type, random_robot_image)) 
                robotina = cv2.resize(robotina, (grid_size, grid_size))
                # Blend the tile with the pixel color
                blended_tile = self.blend_tile_with_pixel(robotina, pixel_color)

                # Place it in the correct position
                mosaic[i * tile_h:(i + 1) * tile_h, j * tile_w:(j + 1) * tile_w] = blended_tile

        return mosaic

    def resize_image(self, image, grid_result):
        image = np.array(image)
        return cv2.resize(grid_result, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_AREA)

    def process_image(self, image, grid_size, tile_type):
        """
        Full pipeline: Preprocess the image, divide it into grids, and analyze.
        """
        # Preprocess the image
        image = self.preprocess_image(image, grid_size)
        # Divide into grids and analyze
        grid_result = self.divide_and_analyze_grid(image, grid_size)

        # Add tile mapping
        grid_result = self.add_tile_mapping(grid_result, grid_size, tile_type.lower())

        # # Compare the original image with the mosaic
        image_comparison = ImageComparison(image, grid_result)
        metrics = image_comparison.generate_metrics_explanation()
        
        
        return grid_result , metrics