我正在尝试使用 Python 和 cv2、numpy、skimage 等从黑白图像中删除“阴影线”(如果图像中存在“阴影线”)。本质上,我的图像可以有 1 或 2 条曲线,如下例所示。但每条线都有一条 1-5 像素外的阴影线,需要删除。我怎样才能在Python中做到这一点?
这是我当前的代码:
import numpy as np
import cv2
import matplotlib.pyplot as plt
from skimage import filters, morphology
from skimage.filters import threshold_otsu
from skimage.filters import threshold_yen
from skimage.filters import try_all_threshold
from scipy import ndimage, datasets,signal
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import RANSACRegressor, LinearRegression
import os
#file_path1 = "C://Development/Imager/images/OCTImages/test_22feb2024_max_vol/max_vol_1-249-20240222-154852.tif"
file_path1 = "C://Development/Imager/images/OCTImages/test_22feb2024_max_vol/max_vol_1-305-20240222-154854.tif"
directory = 'C://Development/Imager/images/OCTImages/test_22feb2024_max_vol/'
output = directory+'done/'
threshold=50
pixel_filter_strength=92
isExist = os.path.exists(output)
if not isExist:
# Create a new directory because it does not exist
os.makedirs(output)
def trim_image(image, top, bottom, left, right):
# Get the dimensions of the image
height, width = image.shape[:2]
# Calculate the new dimensions
new_top = top
new_bottom = height - bottom
new_left = left
new_right = width - right
# Ensure the dimensions are within the bounds of the image
if new_top < 0 or new_bottom > height or new_left < 0 or new_right > width:
raise ValueError("Trim dimensions exceed image bounds")
# Crop the image
trimmed_image = image[new_top:new_bottom, new_left:new_right]
return trimmed_image
def load_image(file_path):
"""
Load an OCT image from the given file path.
Args:
file_path (str): Path to the OCT image file
Returns:
numpy.ndarray: Loaded image as a numpy array
"""
image = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)
if image is None:
raise ValueError(f"Unable to load image from {file_path}")
return image
def edge_detect2(img):
# Read the original image
#img = cv2.imread('test.jpg')
# Display original image
#cv2.imshow('Original', img)
cv2.waitKey(0)
# Convert to graycsale
# img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image for better edge detection
img_blur = cv2.GaussianBlur(img, (3,3), 0)
# Canny Edge Detection
edges = cv2.Canny(image=img_blur, threshold1=100, threshold2=200) # Canny Edge Detection
return edges
def dipit( image):
noiseless_image_bw = cv2.fastNlMeansDenoising(image, None, 40, 7, 21)
return noiseless_image_bw
def processImage( file_path, filename):
image = load_image(file_path)
image = trim_image(image, 50, 485, 27, 36) #top, bottom, left, right
#cleaned_image =remove_isolated_pixels(image, threshold)
#image = segment_corneal_image(image)
cleaned_image =dipit(image)
cleaned_image =edge_detect2(cleaned_image)
cv2.imshow('Cleaned Image', cleaned_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
processImage( file_path1, "max_vol_1-511-20240222-154900")
以下是使用 Python 从黑白图像中去除阴影线的改进方法:
import cv2
import numpy as np
def remove_shadow_lines(image):
"""从黑白图像中去除阴影线。
Args:
image: 黑白图像(二维 numpy 数组)。
Returns:
去除阴影线的图像(二维 numpy 数组)。
"""
# 1. 阈值化图像以创建二值图像。
_, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 2. 使用形态学开运算细化线条。
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 3. 找到连接组件(线条)。
num_labels, labels, stats, _ = cv2.connectedComponentsWithStats(opening, 4, cv2.CV_32S)
# 4. 移除小连接组件(阴影线)。
for i in range(1, num_labels):
area = stats[i, cv2.CC_STAT_AREA]
if area < 50: # 根据阴影线的预期大小调整阈值
labels[labels == i] = 0
# 5. 根据连接组件标签创建遮罩。
mask = (labels > 0).astype(np.uint8) * 255
# 6. 将遮罩应用于原始图像以去除阴影线。
result = cv2.bitwise_and(image, image, mask=mask)
return result
# 从文件中加载图像
image = cv2.imread("image.png", cv2.IMREAD_GRAYSCALE)
# 移除阴影线
result = remove_shadow_lines(image)
# 显示结果
cv2.imshow("Result", result)
cv2.waitKey(0)
这段代码执行以下操作:
- 阈值化图像: 创建二值图像,以便轻松识别线条。
- 形态学开运算: 细化线条并减少阴影线的影响。
- 连接组件分析: 识别图像中的不同线条(包括阴影线)。
- 移除小组件: 根据其大小移除阴影线,保留更大的主要线条。
- 创建遮罩: 生成一个遮罩,突出显示剩余的线条。
- 应用遮罩: 将遮罩应用于原始图像,仅保留没有阴影线的线条。
通过调整参数(例如开运算的迭代次数和小组件的面积阈值),可以针对特定图像微调此代码。
标签:python,opencv From: 78798884