用于预测对象数量的密度图

问题描述 投票:0回答:1

我正在尝试计算视频中物体(在本例中为幼虫)的数量。

这是总体目标,我首先尝试对视频中的所有帧进行密度图。 在更仔细地观察密度图时,我注意到算法正在计算甚至不是幼虫的物体,所以我想让我将问题范围缩小到目前的一帧。 在这些帧中,我对图像中存在的颜色应用了 k 均值聚类。经过一番操作后,我明白了幼虫的颜色是什么,并掩盖了图像的颜色。 经过这些修改后,我在蒙版图像上应用密度图以获得感兴趣的颜色。

现在计数的数量级为 1e3,但实际上这是错误的,因为实际计数约为 50。 当仔细观察密度图时,它是在预测/计算点对象的密度,这就是计算错误的原因。

现在的问题是如何更改密度图,使其不计算点对象,但为我的实际计数提供更接近的答案。

密度图的代码是:

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, Input
from tensorflow.keras.models import Model
from tensorflow.keras.losses import MeanSquaredError
import cv2

# Create the density map estimation model
def create_density_map_model(input_shape):
    inputs = Input(shape=input_shape)
    x = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)
    x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
    density_map = Conv2D(1, (1, 1), activation='linear', padding='same')(x)
    model = Model(inputs=inputs, outputs=density_map)
    return model

# Load the image
image_path = 'color_17.png'
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)

# Extract the alpha channel from the image
alpha_channel = image[:, :, 3]

# Threshold the alpha channel to get a binary mask where non-transparent pixels are white (255) and transparent pixels are black (0)
_, binary_mask = cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)

# Get the height and width of the image
image_height, image_width = image.shape[:2]

# Create and compile the model
input_shape = (image_height, image_width, 1)
model = create_density_map_model(input_shape)
model.compile(optimizer='adam', loss=MeanSquaredError())

# Preprocess the image
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image_normalized = image_gray / 255.0
image_input = np.expand_dims(image_normalized, axis=-1)
image_input = np.expand_dims(image_input, axis=0)

# Predict the density map for the image
predicted_density_map = model.predict(image_input)

# Reshape the predicted density map to match the shape of the image
predicted_density_map = np.reshape(predicted_density_map, (image_height, image_width, 1))

# Create a size factor map (assuming all pixels have the same size factor for simplicity)
size_factor_map = np.ones_like(predicted_density_map)

# Apply the size factor map to the predicted density map
predicted_density_map_filtered = predicted_density_map * size_factor_map

# Expand the dimensions of the binary mask to match the number of channels in the predicted density map
binary_mask_reshaped = np.expand_dims(binary_mask, axis=-1)

# Apply the binary mask to the filtered density map to only keep values where the image isn't transparent
predicted_density_map_filtered = predicted_density_map_filtered * (binary_mask_reshaped / 255.0)

## Apply the binary mask to the filtered density map to only keep values where the image isn't transparent
#predicted_density_map_filtered = predicted_density_map_filtered * (binary_mask / 255.0)

# Save the filtered density map as an image
cv2.imwrite('density_plot_filtered.jpg', (predicted_density_map_filtered * 255.0).astype(np.uint8))

# Calculate the number of larvae predicted from the filtered density map
num_larvae_predicted = int(np.sum(predicted_density_map_filtered))

# Print the number of larvae predicted
print(f"Number of larvae predicted: {num_larvae_predicted}")

我用于第一个代码的视频,即用于识别前 20 种表达颜色的 kmeans 可以在这里找到: https://iitk-my.sharepoint.com/:v:/g/personal/abint21_iitk_ac_in/EexjUqun0pZFmzRTxTBHGFoB8ML2hX5iZ6luH9QVWpLjKA?e=mLQLfb

可以在这里找到没有任何过滤的第一帧:

补充一下,使用 rgba 调色板查看时感兴趣的颜色如下所示:

该图像的密度图如下所示:

我希望这些信息有助于澄清细节。如果需要更多详细信息,请告诉我。

python tensorflow opencv conv-neural-network density-plot
1个回答
0
投票

试试这个代码

import cv2
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# Load the image
image = cv2.imread('larvae_image.jpg', cv2.IMREAD_GRAYSCALE)

# Apply Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(image, (5, 5), 0)

# Perform adaptive thresholding to segment larvae
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# Find contours of the segmented larvae
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Extract features (area and perimeter) from contours
features = []
for contour in contours:
    area = cv2.contourArea(contour)
    perimeter = cv2.arcLength(contour, True)
    features.append([area, perimeter])

# Perform K-means clustering to group larvae
kmeans = KMeans(n_clusters=2, random_state=42).fit(features)
labels = kmeans.labels_

# Count the number of larvae in the desired cluster
larvae_count = np.count_nonzero(labels == 1)  # Assuming cluster 1 represents larvae

# Visualize the results
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
for contour, label in zip(contours, labels):
    color = (0, 255, 0) if label == 1 else (0, 0, 255)  # Green for larvae, Red for non-larvae
    cv2.drawContours(image, [contour], 0, color, 2)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_GRAY2RGB))
plt.title(f'Larvae Count: {larvae_count}')
plt.axis('off')
plt.tight_layout()
plt.show()

稍微修改了簇计数的版本

import cv2
import numpy as np
from sklearn.cluster import DBSCAN
from skimage.filters import frangi
from skimage.morphology import skeletonize, remove_small_objects
import matplotlib.pyplot as plt

image = cv2.imread('larvae_image.jpg', cv2.IMREAD_GRAYSCALE)

frangi_filtered = frangi(image, sigmas=range(1, 10, 2))

skeleton = skeletonize(frangi_filtered > 0.5)

skeleton = remove_small_objects(skeleton, min_size=64, connectivity=2)

features = []
labels, num_features = cv2.connectedComponents(skeleton.astype(np.uint8))
for label in range(1, num_features):
    component = (labels == label).astype(np.uint8)
    area = np.sum(component)
    perimeter = cv2.arcLength(cv2.findContours(component, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0][0], True)
    skeleton_length = np.sum(component * skeleton)
    features.append([area, perimeter, skeleton_length])

dbscan = DBSCAN(eps=0.5, min_samples=5).fit(features)
labels = dbscan.labels_

larvae_count = np.count_nonzero(labels != -1) 

plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(skeleton, cmap='gray')
plt.title('Skeletonized Image')
plt.axis('off')
plt.subplot(1, 3, 3)
colored_image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
for label in set(labels):
    if label == -1:
        continue
    mask = (labels == label).astype(np.uint8) * 255
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    color = (np.random.randint(0, 256), np.random.randint(0, 256), np.random.randint(0, 256))
    cv2.drawContours(colored_image, contours, -1, color, 2)
plt.imshow(colored_image)
plt.title(f'Larvae Count: {larvae_count}')
plt.axis('off')
plt.tight_layout()
plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.