Reputation: 134
Currently, I am trying to use Hessian matrix to detect wrinkles on the forehead. How could I remove out noises around these wrinkles? Below are my current code and result.
from skimage.feature import hessian_matrix, hessian_matrix_eigvals
image = cv2.imread("forehead.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
def detect_ridges(gray, sigma=1.0):
H_elems = hessian_matrix(gray, sigma=sigma)
maxima_ridge, minima_ridge = hessian_matrix_eigvals(H_elems)
return maxima_ridge, minima_ridge
a, b = detect_ridges(gray, sigma=1.0)
fig, axs = plt.subplots(1, 2, figsize=(20, 20))
axs[0].imshow(gray, cmap="gray")
axs[1].imshow(a, cmap="gray")
Upvotes: 4
Views: 644
Reputation: 3855
Simple thresholding and contour detection might give a preliminary results, however further processing is necessary for accurate detection:
#!/usr/bin/env python3
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.feature import hessian_matrix, hessian_matrix_eigvals
im_path = "wrinkle.png"
img = cv2.imread(im_path)
# Convert the img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
def detect_ridges(gray, sigma=1.0):
H_elems = hessian_matrix(gray, sigma=sigma, use_gaussian_derivatives=True)
maxima_ridge, minima_ridge = hessian_matrix_eigvals(H_elems)
return maxima_ridge, minima_ridge
a, b = detect_ridges(gray, sigma=1.0)
a = cv2.normalize(a, None, 255, 0, cv2.NORM_MINMAX, cv2.CV_8U)
a[a<np.mean(a)] = 0
a[a!=0]=255
k = 7
kernel = np.zeros((k, k) ,np.uint8)
kernel[k//2] = 1
a = cv2.morphologyEx(a, cv2.MORPH_OPEN, kernel)
mask = np.zeros_like(a)
# detect the contours on the binary image using cv2.CHAIN_APPROX_NONE
contours, hierarchy = cv2.findContours(image=a, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)
# draw contours on the original image
th_ = 15
for cnt in contours:
if(cv2.contourArea(cnt)>th_):
cv2.drawContours(image=mask, contours=cnt, contourIdx=-1, color=255, thickness=2, lineType=cv2.LINE_AA)
img[mask>0] = (0, 0, 255)
cv2.namedWindow("output", cv2.WINDOW_NORMAL)
cv2.imshow("output", img)
cv2.waitKey(0)
Upvotes: 1
Reputation: 1797
You could first pre-process the image with an edge preserving filter like bilateralFilter(), edgePreservingFilter() etc. A nice tutorial is here.
Edge preserving filters, cartooning an image etc are big topics with several interesting algorithms. Here is one well cited paper, which also has shared code: 100+ Times Faster Weighted Median Filter.
With the right settings, most likely, the wrinkles will remain while the texture-like patterns will be smoothed out.
Upvotes: 0