【发布时间】:2020-08-04 22:15:30
【问题描述】:
我正在做一个预测 MRI 是否有肿瘤的项目,现在下一步是在肿瘤周围绘制一个边界矩形。我能够从 MRI 中提取肿瘤,现在我想得到矩形的对角以将肿瘤与原始图形结合起来。
编辑: 对于某些 MRI 图像,我无法将肿瘤与 MRI 分开,使用 OTSU 方法单独计算阈值,但无法正常工作。 谢谢!
计算阈值:
path=r"ImageProc\Y54.jpg"
img = cv.imread(path,0)
blur = cv.GaussianBlur(img,(5,5),0)
# find normalized_histogram, and its cumulative distribution function
hist = cv.calcHist([blur],[0],None,[256],[0,256])
hist_norm = hist.ravel()/hist.sum()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1
for i in range(1,256):
p1,p2 = np.hsplit(hist_norm,[i]) # probabilities
q1,q2 = Q[i],Q[255]-Q[i] # cum sum of classes
if q1 < 1.e-6 or q2 < 1.e-6:
continue
b1,b2 = np.hsplit(bins,[i]) # weights
# finding means and variances
m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2
v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2
# calculates the minimization function
fn = v1*q1 + v2*q2
if fn < fn_min:
fn_min = fn
thresh = i
# find otsu's threshold value with OpenCV function
ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
print( "{} {}".format(thresh,ret) )
我通过代码的进度是:
import cv2
import matplotlib.pyplot as plt
def show_image(title, image):
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def show_image_plt(title, image, cmap = None):
plt.figure(title)
plt.imshow(image,cmap=cmap)
plt.axis('off')
plt.show()
def cvt_image_colorspace(image, colorspace = cv2.COLOR_BGR2GRAY):
return cv2.cvtColor(image, colorspace)
def median_filtering(image, kernel_size=3):
'''
:param image: grayscale image
:param kernel_size: kernel size should be odd number
:return: blurred image
'''
return cv2.medianBlur(image, kernel_size)
def apply_threshold(image, **kwargs):
'''
:param image: image object
:param kwargs: threshold parameters - dictionary
:return:
'''
threshold_method = kwargs['threshold_method']
max_value = kwargs['pixel_value']
threshold_flag = kwargs.get('threshold_flag', None)
if threshold_flag is not None:
ret, thresh1 = cv2.adaptiveThreshold(image, max_value, threshold_method,cv2.THRESH_BINARY,
kwargs['block_size'], kwargs['const'])
else:
ret, thresh1 = cv2.threshold(image, kwargs['threshold'], max_value, threshold_method)
return thresh1
def sobel_filter(img,x,y,kernel_size = 3):
return cv2.Sobel(img, cv2.CV_8U, x,y, ksize=kernel_size)
path=r"Imageproc\Y54.jpg"
image = cv2.imread(path, 1)
show_image('Original image', image)
#Step one - grayscale the image
grayscale_img = cvt_image_colorspace(image)
#show_image('Grayscaled image', grayscale_img)
#Step two - filter out image
median_filtered = median_filtering(grayscale_img,5)
#show_image('Median filtered', median_filtered)
#testing threshold function
bin_image = apply_threshold(median_filtered, **{"threshold" : 93,
"pixel_value" : 255,
"threshold_method" : cv2.THRESH_BINARY})
otsu_image = apply_threshold(median_filtered, **{"threshold" : 93,
"pixel_value" : 255,
"threshold_method" : cv2.THRESH_BINARY +
cv2.THRESH_OTSU})
#Step 3a - apply Sobel filter
img_sobelx = sobel_filter(median_filtered, 1, 0)
img_sobely = sobel_filter(median_filtered, 0, 1)
# Adding mask to the image
img_sobel = img_sobelx + img_sobely+grayscale_img
#show_image('Sobel filter applied', img_sobel)
#Step 4 - apply threshold
# Set threshold and maxValue
threshold = 160
maxValue = 255
# Threshold the pixel values
thresh = apply_threshold(img_sobel, **{"threshold" : 93,
"pixel_value" : 255,
"threshold_method" : cv2.THRESH_BINARY})
#show_image("Thresholded", thresh)
#Step 3b - apply erosion + dilation
#apply erosion and dilation to show only the part of the image having more intensity - tumor region
#that we want to extract
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(9,9))
erosion = cv2.morphologyEx(median_filtered, cv2.MORPH_ERODE, kernel)
#show_image('Eroded image', erosion)
dilation = cv2.morphologyEx(erosion, cv2.MORPH_DILATE, kernel)
#show_image('Dilatated image', dilation)
#Step 4 - apply thresholding
threshold = 160
maxValue = 255
# apply thresholding
new_thresholding = apply_threshold(dilation, **{"threshold" : 93,
"pixel_value" : 255,
"threshold_method" : cv2.THRESH_BINARY})
show_image('Threshold image after erosion + dilation', new_thresholding)
给定 MRI 的输出图像是:
【问题讨论】:
-
这不是“硬编码的 CNN”,而是经典的图像处理。任何地方都没有神经网络。 — 通过找到肿瘤内的最低和最高 x 和 y 坐标来获取边界框。
-
我已经用正确的预测实现了 CNN 部分,我只需要在肿瘤周围制作边界框
标签: python-3.x image image-processing cv2