marker_separation/py/common.py

169 lines
5.0 KiB
Python

import cv2
import numpy as np
from math import sqrt, pow
def convert_color (color, color_space_a, color_space_b) :
pixel = np.zeros([1, 1, 3], dtype=np.uint8)
if color_space_a == 'RGB' :
pixel = cv2.cvtColor(pixel, cv2.COLOR_BGR2RGB)
elif color_space_a == 'LAB' :
pixel = cv2.cvtColor(pixel, cv2.COLOR_BGR2LAB)
elif color_space_a == 'HSV' :
pixel = cv2.cvtColor(pixel, cv2.COLOR_BGR2HSV)
#default is BGR
pixel[:] = color
if color_space_a == 'RGB' and color_space_b == 'BGR' :
b = cv2.COLOR_RGB2BGR
elif color_space_a == 'BGR' and color_space_b == 'RGB' :
b = cv2.COLOR_BGR2RGB
elif color_space_a == 'RGB' and color_space_b == 'LAB' :
b = cv2.COLOR_RGB2LAB
elif color_space_a == 'LAB' and color_space_b == 'RGB' :
b = cv2.COLOR_LAB2RGB
elif color_space_a == 'BGR' and color_space_b == 'LAB' :
b = cv2.COLOR_BGR2LAB
elif color_space_a == 'LAB' and color_space_b == 'BGR' :
b = cv2.COLOR_LAB2BGR
elif color_space_a == 'HSV' and color_space_b == 'LAB' :
b = cv2.COLOR_HSV2LAB
elif color_space_a == 'LAB' and color_space_b == 'HSV' :
b = cv2.COLOR_LAB2HSV
elif color_space_a == 'RGB' and color_space_b == 'HSV' :
b = cv2.COLOR_RGB2HSV
elif color_space_a == 'HSV' and color_space_b == 'RGB' :
b = cv2.COLOR_HSV2RGB
elif color_space_a == 'BGR' and color_space_b == 'HSV' :
b = cv2.COLOR_BGR2HSV
elif color_space_a == 'HSV' and color_space_b == 'BGR' :
b = cv2.COLOR_HSV2BGR
elif color_space_a == 'RGB' and color_space_b == 'RGB' :
b = None
elif color_space_a == 'BGR' and color_space_b == 'BGR' :
b = None
elif color_space_a == 'LAB' and color_space_b == 'LAB' :
b = None
elif color_space_a == 'HSV' and color_space_b == 'HSV' :
b = None
if b is not None :
cvt = cv2.cvtColor(pixel, b)
else :
cvt = pixel
return cvt[0, 0]
def closest_color (colors, color):
colors = np.array(colors)
color = np.array(color)
distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))
index_of_smallest = np.where(distances == np.amin(distances))
smallest_distance = colors[index_of_smallest]
return smallest_distance[0]
# Works for RGB, BGR, LAB and HSV(?)
def closest_color_euclidean (colors, color) :
#print(len(colors))
mDist = float('inf')
mIdx = -1
color = [float(i) for i in list(color)]
for idx, comp in enumerate(colors) :
comp = [float(i) for i in list(comp)]
dist = euclidean_distance(comp[0], comp[1], comp[2], color[0], color[1], color[2])
#print(f'{color} -> {comp} = {dist}')
if dist < mDist :
mDist = dist
mIdx = idx
return colors[mIdx], mDist
def closest_color_weighted_euclidean (colors, color, space) :
#print(len(colors))
mDist = float('inf')
mIdx = -1
color = [float(i) for i in list(color)]
for idx, comp in enumerate(colors) :
comp = [float(i) for i in list(comp)]
if space == 'BGR' :
dist = weighted_euclidean_distance(comp[2], comp[1], comp[0], color[2], color[1], color[0])
elif space == 'RGB' :
dist = weighted_euclidean_distance(comp[0], comp[1], comp[2], color[0], color[1], color[2])
else :
raise Exception(f'closest_color_weighted_euclidean does not support color space {space}')
break
#print(f'{color} -> {comp} = {dist}')
if dist < mDist :
mDist = dist
mIdx = idx
return colors[mIdx], mDist
def create_colored_image (width, height, bgr_color):
image = np.zeros((height, width, 3), np.uint8)
image[:] = bgr_color
return image
def remove_from_list (l, item) :
new_array = []
for i in l :
if not list_match(i, item) :
new_array.append(i)
return new_array
def list_match (a, b) :
for i in range(len(a)) :
if a[i] != b[i] :
return False
return True
def rgb_euclidean_distance(rgba, rgbb) :
return euclidean_distance(rgba[0], rgba[1], rgba[2], rgbb[0], rgbb[1], rgbb[2])
def bgr_euclidean_distance(bgra, bgrb) :
return euclidean_distance(bgra[2], bgra[1], bgra[0], bgrb[2], bgrb[1], bgrb[0])
def numpy_distance (r1, g1, b1, r2, g2, b2) :
p0 = np.array([r1, g1, b1])
p1 = np.array([r2, g2, b2])
d = np.linalg.norm(p0 - p1)
return d
#return sqrt(pow(abs(r1-r2), 2) + pow(abs(g1-g2), 2) + pow(abs(b1-b2), 2))
def euclidean_distance (r1, g1, b1, r2, g2, b2):
d = 0.0
d = sqrt((r2 - r1)**2 + (g2 - g1)**2 + (b2 - b1)**2)
return d
def weighted_euclidean_distance (r1, g1, b1, r2, g2, b2) :
R = 0.30
G = 0.59
B = 0.11
#print(type(r1))
return sqrt( ((r2-r1) * R)**2 + ((g2-g1) * G)**2 + ((b2-b1) * B)**2 )
def to_luma (color, space) :
color = [float(i) for i in list(color)]
if space == 'RGB' :
return rgb_to_luma(color[0], color[1], color[2])
elif space == 'BGR' :
return rgb_to_luma(color[2], color[1], color[0])
def rgb_to_luma (r, g, b) :
R = 0.2126
G = 0.7152
B = 0.0722
return (r * R) + (g * G) + (b * B)
def convertScale(img, alpha, beta):
"""Add bias and gain to an image with saturation arithmetics. Unlike
cv2.convertScaleAbs, it does not take an absolute value, which would lead to
nonsensical results (e.g., a pixel at 44 with alpha = 3 and beta = -210
becomes 78 with OpenCV, when in fact it should become 0).
"""
new_img = img * alpha + beta
new_img[new_img < 0] = 0
new_img[new_img > 255] = 255
return new_img.astype(np.uint8)