OpenCV – как получить значения пикселей на стыках компонентов разных цветов из изображения? ⇐ Python

Программы на Python
Anonymous
OpenCV – как получить значения пикселей на стыках компонентов разных цветов из изображения?

Сообщение Anonymous »

У меня есть зернистая структура с различной случайной ориентацией зерен, представленной разными цветами на изображении, созданном в результате моделирования фазового поля. Мне нужно идентифицировать и получить значения пикселей для каждого зерна, а также найти координаты пикселей на стыках (тройных стыках и стыках более высокого порядка) и вдоль границ.
Структура зерна с разной ориентацией
Изображение

Зернистая структура с выделением границ
Изображение

Я попробовал несколько методов обработки изображений, а также попытался решить эту проблему, внедрив алгоритм, который обнаруживает изменение цвета и связность, а также классифицирует зерна, но не смог получить значения пикселей и точки соединения из кода. Кто-нибудь может помочь? Вот один из подходов, которые я опробовал.
import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read the image
image = cv2.imread('image_path', cv2.IMREAD_GRAYSCALE)

# Apply threshold to create a binary image
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)

# Apply morphological operations to remove small noise and text
kernel = np.ones((3, 3), np.uint8)
clean_image = cv2.morphologyEx(binary_image, cv2.MORPH_OPEN, kernel)

# Find connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(clean_image, 8, cv2.CV_32S)

# Size threshold to filter out small connected components
size_threshold = 30

# Create a color map for visualization
colors = [np.array([np.random.randint(256), np.random.randint(256), np.random.randint(256)], dtype=np.uint8) for _ in range(num_labels)]
colors[0] = [255, 255, 255] # Setting background color to white

# Create a color image for visualization
output_image = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)

# Variable to track the new labels for the larger connected components
new_label = 1
desired_label = list(range(50))
for i in range(1, num_labels):
coordinates = np.column_stack(np.where(labels == i))
x = stats[i, cv2.CC_STAT_LEFT]
y = stats[i, cv2.CC_STAT_TOP]
w = stats[i, cv2.CC_STAT_WIDTH]
h = stats[i, cv2.CC_STAT_HEIGHT]
area = stats[i, cv2.CC_STAT_AREA]
(cX, cY) = centroids
if coordinates.shape[0] > size_threshold:
if new_label in desired_label:
output_image[labels == i] = colors[new_label]
cv2.rectangle(output_image, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.circle(output_image, (int(cX), int(cY)), 4, (0, 0, 255), -1)
else:
output_image[labels == i] = [255, 255, 255]
new_label += 1

plt.figure(2)
print(f"Number of connected components (labels): {new_label - 1}")
plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))
plt.axis('off')

# Define a smaller kernel for the morphological operation
kernel_dilate = np.ones((2, 2), np.uint8)

# Apply dilation to expand the white areas with only one iteration
dilated_image = cv2.dilate(output_image, kernel_dilate, iterations=1)

plt.figure(3)
plt.imshow(cv2.cvtColor(dilated_image, cv2.COLOR_BGR2RGB))
plt.axis('off')

# Convert the white areas of the dilated image to black and the black areas to white
intersection_image = cv2.bitwise_not(dilated_image)

# Convert the image to grayscale
intersection_image_gray = cv2.cvtColor(intersection_image, cv2.COLOR_BGR2GRAY)

# Apply binary thresholding to isolate the lines
_, intersection_image_binary = cv2.threshold(intersection_image_gray, 127, 255, cv2.THRESH_BINARY)

# Find the skeleton of the black lines
skeleton = cv2.ximgproc.thinning(intersection_image_binary)

# Apply a cross-shaped kernel to find intersection points
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
intersection_points = cv2.morphologyEx(skeleton, cv2.MORPH_HITMISS, cross_kernel)

# Draw the intersection points on the original image
intersection_image_with_points = intersection_image.copy()
intersection_image_with_points[intersection_points > 0] = [0, 0, 255] # Marking the intersection points in red

plt.figure(4)
plt.imshow(cv2.cvtColor(intersection_image_with_points, cv2.COLOR_BGR2RGB))
plt.axis('off')

y_coords, x_coords = np.where(intersection_points != 0)

# Draw the intersection points on the output_image
for x, y in zip(x_coords, y_coords):
cv2.circle(output_image, (x, y), 3, (0, 0, 255), -1) # Marking the intersection points in red

plt.figure(5)
plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()


Подробнее здесь: https://stackoverflow.com/questions/768 ... ferent-col

Вернуться в «Python»