generated from Hazel/python-project
heatmaps
This commit is contained in:
parent
df4b949dd2
commit
6126e675f1
@ -215,7 +215,6 @@ def kernel_detection(blurred, mask, edge_threshold=30, profile_length=21):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def kernel_detection_box(blurred, mask, edge_threshold=30, profile_length=21):
|
def kernel_detection_box(blurred, mask, edge_threshold=30, profile_length=21):
|
||||||
def box_function(x, amp, center, width):
|
def box_function(x, amp, center, width):
|
||||||
"""Simple box profile: flat region with sharp transitions."""
|
"""Simple box profile: flat region with sharp transitions."""
|
||||||
@ -295,6 +294,117 @@ def deconvolution(image_file, edge_threshold=30, profile_length=21):
|
|||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def sharpness_heatmap(image, block_size=32, threshold=30):
|
||||||
|
"""
|
||||||
|
Compute a sharpness heatmap using color-aware Laplacian variance over blocks,
|
||||||
|
generate a binary mask highlighting blurred areas, and smooth the edges of the mask.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image: BGR or RGB image (NumPy array).
|
||||||
|
block_size: Size of the square block to compute sharpness.
|
||||||
|
sigma: Standard deviation for Gaussian smoothing of the heatmap.
|
||||||
|
threshold: Sharpness threshold to define blurred regions (between 0 and 1).
|
||||||
|
smoothing_sigma: Standard deviation for Gaussian smoothing of the binary mask edges.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
blurred_mask: Binary mask highlighting blurred areas (0 = sharp, 255 = blurred).
|
||||||
|
"""
|
||||||
|
if image.ndim != 3 or image.shape[2] != 3:
|
||||||
|
raise ValueError("Input must be a color image (3 channels)")
|
||||||
|
|
||||||
|
h, w, _ = image.shape
|
||||||
|
heatmap = np.zeros((h // block_size, w // block_size))
|
||||||
|
|
||||||
|
# Calculate sharpness for each block
|
||||||
|
for y in range(0, h - block_size + 1, block_size):
|
||||||
|
for x in range(0, w - block_size + 1, block_size):
|
||||||
|
block = image[y:y + block_size, x:x + block_size, :]
|
||||||
|
sharpness_vals = []
|
||||||
|
|
||||||
|
for c in range(3): # For R, G, B channels
|
||||||
|
channel = block[..., c]
|
||||||
|
lap_var = cv2.Laplacian(channel, cv2.CV_64F).var()
|
||||||
|
sharpness_vals.append(lap_var)
|
||||||
|
|
||||||
|
# Use average sharpness across color channels
|
||||||
|
heatmap[y // block_size, x // block_size] = np.mean(sharpness_vals)
|
||||||
|
|
||||||
|
print(heatmap)
|
||||||
|
|
||||||
|
# Threshold the heatmap to create a binary mask (blurred regions)
|
||||||
|
mask = heatmap < threshold
|
||||||
|
mask = (mask * 255).astype(np.uint8) # Convert to binary mask (0, 255)
|
||||||
|
|
||||||
|
# Display Heatmap
|
||||||
|
plt.subplot(1, 2, 1)
|
||||||
|
plt.imshow(heatmap, cmap='hot', interpolation='nearest')
|
||||||
|
plt.title("Sharpness Heatmap")
|
||||||
|
plt.colorbar(label='Sharpness')
|
||||||
|
|
||||||
|
# Display Smoothed Mask
|
||||||
|
plt.subplot(1, 2, 2)
|
||||||
|
plt.imshow(mask, cmap='gray', interpolation='nearest')
|
||||||
|
plt.title("Smoothed Mask for Blurred Areas")
|
||||||
|
plt.colorbar(label='Blurred Mask')
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
return smoothed_mask
|
||||||
|
|
||||||
|
|
||||||
|
def graininess_heatmap(image, block_size=32, threshold=100):
|
||||||
|
"""
|
||||||
|
Compute a graininess heatmap using local variance (texture/noise) over blocks.
|
||||||
|
No smoothing or blurring is applied.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image: BGR or RGB image (NumPy array).
|
||||||
|
block_size: Size of the square block to compute variance (graininess).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
graininess_map: Heatmap highlighting the graininess (texture/noise) in the image.
|
||||||
|
"""
|
||||||
|
if image.ndim != 3 or image.shape[2] != 3:
|
||||||
|
raise ValueError("Input must be a color image (3 channels)")
|
||||||
|
|
||||||
|
h, w, _ = image.shape
|
||||||
|
graininess_map = np.zeros((h // block_size, w // block_size))
|
||||||
|
|
||||||
|
# Calculate variance for each block
|
||||||
|
for y in range(0, h - block_size + 1, block_size):
|
||||||
|
for x in range(0, w - block_size + 1, block_size):
|
||||||
|
block = image[y:y + block_size, x:x + block_size, :]
|
||||||
|
variance_vals = []
|
||||||
|
|
||||||
|
for c in range(3): # For R, G, B channels
|
||||||
|
channel = block[..., c]
|
||||||
|
variance = np.var(channel)
|
||||||
|
variance_vals.append(variance)
|
||||||
|
|
||||||
|
# Use average variance across color channels for graininess
|
||||||
|
graininess_map[y // block_size, x // block_size] = np.mean(variance_vals)
|
||||||
|
|
||||||
|
|
||||||
|
mask = graininess_map < threshold
|
||||||
|
mask = (mask * 255).astype(np.uint8) # Convert to binary mask (0, 255)
|
||||||
|
|
||||||
|
# Display graininess_map
|
||||||
|
plt.subplot(1, 2, 1)
|
||||||
|
plt.imshow(graininess_map, cmap='hot', interpolation='nearest')
|
||||||
|
plt.title("Graininess Heatmap")
|
||||||
|
plt.colorbar(label='Graininess')
|
||||||
|
|
||||||
|
# Display Smoothed Mask
|
||||||
|
plt.subplot(1, 2, 2)
|
||||||
|
plt.imshow(mask, cmap='gray', interpolation='nearest')
|
||||||
|
plt.title("Mask for Blurred Areas")
|
||||||
|
plt.colorbar(label='Blurred Mask')
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
return graininess_map
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -302,4 +412,8 @@ if __name__ == "__main__":
|
|||||||
img_file = "assets/real_test.jpg"
|
img_file = "assets/real_test.jpg"
|
||||||
|
|
||||||
#demo("assets/omas.png")
|
#demo("assets/omas.png")
|
||||||
deconvolution(img_file, edge_threshold=5)
|
# deconvolution(img_file, edge_threshold=5)
|
||||||
|
|
||||||
|
image = cv2.imread(img_file)
|
||||||
|
test = graininess_heatmap(image)
|
||||||
|
heatmap = sharpness_heatmap(image)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user