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
CodePudding user response:
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 defining max_contour
near max_aspect
, which is also accessible to the line with the mask.
max_aspect = 0
max_contour = 0
CodePudding user response:
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
aspect = w/h
if aspect > max_aspect:
max_aspect = aspect
max_contour = cntr
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 code max_contour = cntr
was never executed.
This would be caused by contours
being empty, or aspect > max_aspect
always being false.