我正在嘗試清理一些胸部 X 光資料以提供給 CNN。在我的資料集中,目前有許多影像,其中骨骼顯示為白色(像素值高于背景),如下所示:
而其他人則以比背景更深的顏色顯示骨骼,如下所示:
你能告訴我一種標記這兩者的方法嗎?我沒有關于影像的其他外部資訊,盡管可以假設它們的大小相同(
假設它們具有相同的大小(大約 1000x2000)并且第一行像素有超過 1 個不同的值(即不是空白邊框),我撰寫了這個簡單的代碼來比較中間像素和頂部 -留下一個(可能是背景的一部分)。
if img[0,0] > img[500, 500]: # if background lighter than center
img = 255 - img # make the image negative
As you can see even from these samples I posted, this comparison is not always a good indicator (sometimes there is a halo round the background or pixel in [500,500] can be similar to background). Is there some more reliable other way to detect if an image of this kind is negative or not?
Consider that in the dataset are some images with very few details and shading, such as

uj5u.com熱心網友回復:
一種可能的解決方案包括均衡輸入影像,然后僅應用固定閾值進行閾值處理。我們可以估計白色像素的數量并與閾值進行比較以確定是否需要應用校正。
讓我們看看代碼:
# 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)
然后,我們根據閾值檢查這個值,看看我們是否必須應用校正。您可以選擇校正原始影像和均衡影像:
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)
第二張影像被校正。以下是兩種可能結果的影像:
原文倒置:
均衡倒置:
現在,除了影像反轉之外,您可能還需要做一些額外的后期處理來提高原件的亮度和對比度。我們可以使用 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)
這是增強的影像:
uj5u.com熱心網友回復:
按照Christoph Rackwitz的建議,我用這種方法得到了很好的結果:
- 可選地標準化影像
- 從影像中提取角點,更有可能是背景(我只考慮了頂角)
- 從影像中提取中心
- 將區域與閾值(影像的固定或平均灰度值)進行比較,獲得真值串列
- 比較閾值以上的像素數量(百分比)以確定背景是否比影像中心更亮或更暗:因此決定反轉值。
def invert_if_negative(img):
img = my_contrast_stretch(img)
# assuming image has fixed size of (1396, 1676)
# corners
top_left = img[:200, :200].flatten()
top_right = img[:200, 1250:].flatten()
# more or less center
center = img[1000:1300, 500:800].flatten()
threshold = 120 # or computed from average
top_left = top_left > threshold
top_right = top_right > threshold
center = center > threshold
perc_white_corners = (sum(top_left) sum(top_right)) / (len(top_left) len(top_right))
perc_white_center = sum(center) / len(center)
if perc_white_corners > perc_white_center:
img = 255 - img
return img
def my_contrast_stretch(img):
if img.dtype == np.float64:
img = (img * 255).astype(np.uint8)
M=np.max(img)
m=np.min(img)
res = img - m
res = res * (255 / (M - m))
return res.astype(np.uint8)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425473.html
標籤:python image opencv image-processing data-cleaning
