Wednesday, 20 September 2023

RGB Values Extracrtion and Comparison using Open CV

I am working on a project where I have an image with a strip and a main card with many colors. Problem Statement: I have compare the colors from the strip with the main card and give some result. So, I have splitted the image into three parts and trying to extarct the RGB values from both main card and strip and compare the values.

I found the countours and splitted the image, but I am unabel to find any way to get the RGB values of the colors or the co-ordinates of the color on the chart(less important approch).

Here is the below code:-

`import cv2
from skimage.io import imread
import matplotlib.pyplot as plt
import numpy as np

img = imread("image_name.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred,10,0,apertureSize=5,L2gradient=True)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

result = img.copy()
i=0
for contour in contours:
    area = cv2.contourArea(contour)
    min_area = 90000
    if area > min_area:
        cv2.drawContours(result, [contour], -1, (0, 255, 0), 2)
        x, y, w, h = cv2.boundingRect(contour)
        i = i +1
        print(f"Coordinates: x={x}, y={y}, width={w}, height={h}")

x = 105
y = 308
width = 374
height = 740
roi = img[y:y+height, x:x+width]  #New splitted image of the main card.`

I tried this as well:-

from PIL import Image, ImageDraw, ImageFont
image = Image.open('dotted_pic_1.jpg')
image = image.convert('RGB')
x, y = 100, 150
pixel_rgb = image.getpixel((x, y))
rgb_string = f"RGB: {pixel_rgb[0]}, {pixel_rgb[1]}, {pixel_rgb[2]}"
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("arial.ttf", 16)
text_position = (x, y + 20)
text_color = (255, 255, 255)
draw.text(text_position, rgb_string, fill=text_color, font=font)
image.save('output_image.jpg')
image.show()

but result is not up to the mark.

The Image on which I am performing these operations

UPDATE

So, I was able to find the colors and coordinates of the main chart on the right side.

result = card_img.copy()
i=0
num = 0


for contour in contours:
    area = cv2.contourArea(contour)
    min_area = 1000 # Adjust this threshold as needed
    if area>min_area:
        cv2.drawContours(result, [contour], -1, (0, 255, 0), 2)
        x, y, w, h = cv2.boundingRect(contour)
        i = i +1
        # Print the coordinates (you can modify this part to save coordinates)
        #print(f"Coordinates: x={x}, y={y}, width={w}, height={h}")
        
        x = x
        y = y

        # Define the width and height of the region
        width = w
        height = h

        # Extract the region of interest (ROI)
        roi_strip = card_img[y:y+height, x:x+width]
        
        rgb_value = np.mean(roi_strip, axis=(0, 1))
        B = rgb_value[0]
        G = rgb_value[1]
        R = rgb_value[2]
        
        print(get_color_name(B,G,R))
        
        plt.title("Contours")
        plt.imshow(roi_strip)
        plt.show()

It gives me all the colors and coordinates of the color boxes on the right side. I am now facing an issue with the left strip:-

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Specify the dimensions of the region to remove
left_margin_to_remove = 35  # Width to remove from the left side
right_margin_to_remove = 30  # Width to remove from the right side
top_margin_to_remove = 255  # Height to remove from the top
bottom_margin_to_remove = 37  # Height to remove from the bottom

# Get the dimensions of the image
height, width, _ = strip_img.shape

# Crop the image to remove the specified regions
image_cropped = strip_img[top_margin_to_remove:height - bottom_margin_to_remove, left_margin_to_remove:width - right_margin_to_remove]

# Display or save the modified image
cv2.imshow('Cropped Image', image_cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()

sharp_kernel = np.array([[-1,-1,-1],
                         [-1, 9,-1],
                         [-1,-1,-1]])

sharpened_image = cv2.filter2D(image_cropped, -1, sharp_kernel)

dst = cv2.fastNlMeansDenoisingColored(sharpened_image, None, 6, 6, 7, 21)
cv2.imshow('Denoised Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

strip_grey = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(strip_grey, 200, 250, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

contours, _ = cv2.findContours(strip_grey, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

This is finding only one contour for the image. enter image description here

I want to find all the colors from the strip and then create a new image something like this:- Final Output

This image has the strip on the left and the main chart on the right. The main contains all the colors and black wherever there's no color in the main chart.

I am new to Open-CV and just trying hit and trial here.



from RGB Values Extracrtion and Comparison using Open CV

No comments:

Post a Comment