如何解决错误 UnboundLocalError: local variable 'max_contour'赋值前引用
Hello everyone I hope you are doing well I have implemented the following code. 这是我的数据集 https://drive.google.com/drive/folders/1ARQLty-f7i_W6fvvcIx-3VUUzjb3o1KX?usp=sharing
I read the dicom files from the folder and apply some preprocessing to it to the segment area.我开发了一个分割区域的函数,但是我收到以下错误 I got the following error when I run the code
How can I solve that
UnboundLocalError: local variable 'max_contour' referenced before assignment
from matplotlib.pyplot import imshow
import matplotlib.pyplot as plt
import pydicom
import numpy
import tkinter
from tkinter import filedialog
import os
import numpy as np
import pydicom as dcm
import cv2
def window_image(img, window_center,window_width, intercept, slope, rescale=True):
img = (img*slope +intercept) #for translation adjustments given in the dicom file.
img_min = window_center - window_width//2 #minimum HU level
img_max = window_center + window_width//2 #maximum HU level
img[img<img_min] = img_min #set img_min for all HU levels less than minimum HU level
img[img>img_max] = img_max #set img_max for all HU levels higher than maximum HU level
if rescale:
img = (img - img_min) / (img_max - img_min)*255.0
return img
def preprocess_dicom(img,outdir,image_path):
ht, wd = img.shape[:2]
# convert to grayscale
#gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# get external contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
max_aspect=0
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
aspect = w/h
if aspect > max_aspect:
max_aspect = aspect
max_contour = cntr
# create mask from max_contour
mask = np.zeros((ht,wd), dtype=np.uint8)
mask = cv2.drawContours(mask, [max_contour], 0, (255), -1)
# dilate mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
# invert mask
mask = 255 - mask
# mask out region in input
result = img.copy()
result = cv2.bitwise_and(result, result, mask=mask)
# save resulting image
# Open the outlined image
fig, ax = plt.subplots(1,2)
ax[0].imshow(img,'gray');
ax[1].imshow(result,'gray');
cv2.imwrite(os.path.join(outdir,os.path.basename(image_path).replace(".dcm", "_segment.png")), result)
return result
def get_first_of_dicom_field_as_int(x):
#get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)
if type(x) == dcm.multival.MultiValue: return int(x[0])
else: return int(x)
def get_windowing(data):
dicom_fields = [data[('0028','1050')].value, #window center
data[('0028','1051')].value, #window width
data[('0028','1052')].value, #intercept
data[('0028','1053')].value] #slope
return [get_first_of_dicom_field_as_int(x) for x in dicom_fields]
root=tkinter.Tk()
root.withdraw()
currdir=os.getcwd()
PathDicom=filedialog.askdirectory(parent=root,initialdir=currdir,title='Please select a folder with DICOM')
if len (PathDicom)>0:
print(("You chose %s")%PathDicom)
lstFilesDCM=[]
for dirName,subdirList,fileList in os.walk(PathDicom):
for filename in fileList:
if ".dcm" in filename.lower():
lstFilesDCM.append(os.path.join(dirName,filename))
RefDs=pydicom.dcmread(lstFilesDCM[0])
ConstPixelDims=(int(RefDs.Rows),int(RefDs.Columns),len(lstFilesDCM))
cal=RefDs.RescaleIntercept
ArrayDicom=numpy.zeros(ConstPixelDims,dtype=RefDs.pixel_array.dtype)
ind = 0
folder_name=r'C:\Users\Hammad\Desktop'
for i in lstFilesDCM:
for j in range(1, len(lstFilesDCM)):
ds=pydicom.dcmread(i)
ArrayDicom[:,:,lstFilesDCM.index(i)]=ds.pixel_array
window_center , window_width, intercept, slope = get_windowing(ds)
output = window_image(ArrayDicom[:,:,j], window_center, window_width, intercept, slope)
imshow(output,cmap='gray')
output = output - np.min(output)
output = output / np.max(output)
output = (output * 255).astype(np.uint8)
imgsegment=preprocess_dicom(output,r'C:\Users\Hammad\Desktop\manifest-1643119746471\manifest-1645243048125\CPTAC-SAR',i)
RefDs.PixelData = imgsegment.tobytes()
RefDs.save_as( folder_name+ '/{0}.dcm'.format(ind))
ind = ind+1
Can anybody please help me in this
Hello everyone I hope you are doing well
I have implemented the following code.
Here is my dataset https://drive.google.com/drive/folders/1ARQLty-f7i_W6fvvcIx-3VUUzjb3o1KX?usp=sharing
I read the dicom files from the folder and apply some preprocessing to it to the segment area. I have developed a function that segment the area, but I am getting the following error where
I got the following error when I run the code
How can I solve that
UnboundLocalError: local variable 'max_contour' referenced before assignment
from matplotlib.pyplot import imshow
import matplotlib.pyplot as plt
import pydicom
import numpy
import tkinter
from tkinter import filedialog
import os
import numpy as np
import pydicom as dcm
import cv2
def window_image(img, window_center,window_width, intercept, slope, rescale=True):
img = (img*slope +intercept) #for translation adjustments given in the dicom file.
img_min = window_center - window_width//2 #minimum HU level
img_max = window_center + window_width//2 #maximum HU level
img[img<img_min] = img_min #set img_min for all HU levels less than minimum HU level
img[img>img_max] = img_max #set img_max for all HU levels higher than maximum HU level
if rescale:
img = (img - img_min) / (img_max - img_min)*255.0
return img
def preprocess_dicom(img,outdir,image_path):
ht, wd = img.shape[:2]
# convert to grayscale
#gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# get external contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
max_aspect=0
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
aspect = w/h
if aspect > max_aspect:
max_aspect = aspect
max_contour = cntr
# create mask from max_contour
mask = np.zeros((ht,wd), dtype=np.uint8)
mask = cv2.drawContours(mask, [max_contour], 0, (255), -1)
# dilate mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
# invert mask
mask = 255 - mask
# mask out region in input
result = img.copy()
result = cv2.bitwise_and(result, result, mask=mask)
# save resulting image
# Open the outlined image
fig, ax = plt.subplots(1,2)
ax[0].imshow(img,'gray');
ax[1].imshow(result,'gray');
cv2.imwrite(os.path.join(outdir,os.path.basename(image_path).replace(".dcm", "_segment.png")), result)
return result
def get_first_of_dicom_field_as_int(x):
#get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)
if type(x) == dcm.multival.MultiValue: return int(x[0])
else: return int(x)
def get_windowing(data):
dicom_fields = [data[('0028','1050')].value, #window center
data[('0028','1051')].value, #window width
data[('0028','1052')].value, #intercept
data[('0028','1053')].value] #slope
return [get_first_of_dicom_field_as_int(x) for x in dicom_fields]
root=tkinter.Tk()
root.withdraw()
currdir=os.getcwd()
PathDicom=filedialog.askdirectory(parent=root,initialdir=currdir,title='Please select a folder with DICOM')
if len (PathDicom)>0:
print(("You chose %s")%PathDicom)
lstFilesDCM=[]
for dirName,subdirList,fileList in os.walk(PathDicom):
for filename in fileList:
if ".dcm" in filename.lower():
lstFilesDCM.append(os.path.join(dirName,filename))
RefDs=pydicom.dcmread(lstFilesDCM[0])
ConstPixelDims=(int(RefDs.Rows),int(RefDs.Columns),len(lstFilesDCM))
cal=RefDs.RescaleIntercept
ArrayDicom=numpy.zeros(ConstPixelDims,dtype=RefDs.pixel_array.dtype)
ind = 0
folder_name=r'C:\Users\Hammad\Desktop'
for i in lstFilesDCM:
for j in range(1, len(lstFilesDCM)):
ds=pydicom.dcmread(i)
ArrayDicom[:,:,lstFilesDCM.index(i)]=ds.pixel_array
window_center , window_width, intercept, slope = get_windowing(ds)
output = window_image(ArrayDicom[:,:,j], window_center, window_width, intercept, slope)
imshow(output,cmap='gray')
output = output - np.min(output)
output = output / np.max(output)
output = (output * 255).astype(np.uint8)
imgsegment=preprocess_dicom(output,r'C:\Users\Hammad\Desktop\manifest-1643119746471\manifest-1645243048125\CPTAC-SAR',i)
RefDs.PixelData = imgsegment.tobytes()
RefDs.save_as( folder_name+ '/{0}.dcm'.format(ind))
ind = ind+1
Can anybody please help me in this
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是代码中定义
max_contour
的唯一位置。因此,如果您收到该错误,则一定意味着max_contour = cntr
代码行从未执行过。这可能是由于
contours
为空,或者aspect > > 造成的。 max_aspect
始终为 false。This the only place in the code where
max_contour
is defined. So, if you're getting that error, it must mean that the line of codemax_contour = cntr
was never executed.This would be caused by
contours
being empty, oraspect > max_aspect
always being false.max_contour
似乎是在 for 循环中首先定义的,但是您在 for 循环之外使用它 (mask = cv2.drawContours(mask, [max_contour], 0, (255) ,-1)
)。尝试在max_aspect
附近定义max_contour
,也可以通过带有遮罩的线访问。编辑:问题是,仅当且仅当轮廓列表中存在轮廓(变量
contours
)时才会更新max_contour
。因此,max_contour
的默认值不会被drawContours
接受,因为它期望一个非空轮廓(因此(-215:Assertion failed) npoints > 0您遇到的错误)。
解决方案是仅在找到轮廓时才创建蒙版。如果没有,我们可以返回原始图像,因为没有可应用的掩模。
所以代码看起来像这样:
max_contour
seems to be getting defined first within the for loop, but you're using it outside the for loop (mask = cv2.drawContours(mask, [max_contour], 0, (255), -1)
). Try definingmax_contour
nearmax_aspect
, which is also accessible to the line with the mask.Edit: The issue is that
max_contour
is only updated if and only if a contour exists in the list of contours (the variablecontours
). So the default value formax_contour
will not be accepted bydrawContours
since it's expecting a non-empty contour (hence the(-215:Assertion failed) npoints > 0
error you encountered).The solution would be to only create a mask if a contour is found. If not, we could return the original image since there's no mask to apply.
So the code would look something like this: