rik*_*eah 0 python opencv image image-processing data-cleaning
我正在尝试清理一些胸部 X 光数据以提供给 CNN。在我的数据集中,当前有许多图像的骨骼显示为白色(像素值高于背景),如下所示:
你能告诉我一种给两者贴上标签的方法吗?我没有关于该图像的其他外部信息,尽管可以假设它们的大小相同(
假设它们具有相同的大小(大约 1000x2000)并且第一行像素有超过 1 个不同的值(即不是空白边框),我编写了这个简单的代码来将中间像素与顶部进行比较 -左边一个(可能是背景的一部分)。
if img[0,0] > img[500, 500]: # if background lighter than center
img = 255 - img # make the image negative
Run Code Online (Sandbox Code Playgroud)
即使从我发布的这些示例中您也可以看到,这种比较并不总是一个好的指标(有时背景周围有光环,或者 [500,500] 中的像素可能与背景相似)。是否有更可靠的其他方法来检测此类图像是否为负片?
考虑到数据集中有一些细节和阴影很少的图像,例如
一种可能的解决方案涉及均衡输入图像,然后仅应用固定阈值进行阈值处理。我们可以估计白色像素的数量并与阈值进行比较来决定是否需要应用校正。
我们看一下代码:
# Imports:
import numpy as np
import cv2
# Image path
path = "D://opencvImages//"
fileName = "RPWBn.png"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Convert RGB to grayscale:
originalGrayscale = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Equalize histogram
grayscaleImage = cv2.equalizeHist(originalGrayscale)
# It might be interesting to you to check out the image equalization:
cv2.imshow("Image Equalized", grayscaleImage)
cv2.waitKey(0)
# Binarize the image with a fixed threshold:
minThresh = 128
_, binaryImage = cv2.threshold(grayscaleImage, minThresh, 255, cv2.THRESH_BINARY)
# Compute the percent of white pixels:
(imageHeight, imageWidth) = binaryImage .shape[:2]
whitePercent = cv2.countNonZero(binaryImage)/(imageHeight * imageWidth)
Run Code Online (Sandbox Code Playgroud)
然后,我们根据阈值检查该值,看看是否必须应用校正。您可以选择校正原始图像和均衡后的图像:
if whitePercent > 0.5:
print("Correcting images...")
# Correct the original (unequalized) image:
originalGrayscale = 255 - originalGrayscale
cv2.imshow("Correction - Original Image", originalGrayscale)
# Correct the equalized image:
grayscaleImage = 255 - grayscaleImage
cv2.imshow("Correction - Equalized Image", grayscaleImage )
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)
第二张图像已修正。以下是两种可能结果的图像:
原来的倒置:
均衡反转:
现在,除了图像反转之外,您可能还需要进行一些额外的后处理以提高原始图像的亮度和对比度。我们可以使用 CLAHE 方法来实现这一点。让我们对原始的、未均衡的图像进行后处理:
# Improve the brightness + contrast of the original image via
# CLAHE.
# Gray to BGR conversion:
originalGrayscale = cv2.cvtColor(originalGrayscale , cv2.COLOR_GRAY2BGR)
# Conversion to LAB:
lab = cv2.cvtColor(originalGrayscale, cv2.COLOR_BGR2LAB)
# Split the channels:
l, a, b = cv2.split(lab)
# Apply CLAHE to L-channel:
# You might need to fiddle with the parameters:
clahe = cv2.createCLAHE(clipLimit=7.0, tileGridSize=(1, 1))
cl = clahe.apply(l)
# Merge the CLAHE enhanced L-channel with the a and b channel:
limg = cv2.merge((cl, a, b))
# Conversion from LAB to BGR:
final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
cv2.imshow("Original Corrected and Enhanced", final)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)
这是增强后的图像: