Ejemplo n.º 1
0
    def getCubicInputChunk(self, center_xyz, maxWidth_mm):
        center_irc = xyz2irc(center_xyz, self.origin_xyz, self.vxSize_xyz, self.direction_tup)

        ct_start = [int(round(i)) for i in xyz2irc(tuple(x - maxWidth_mm / 2 for x in center_xyz), self.origin_xyz, self.vxSize_xyz, self.direction_tup)]
        ct_end = [int(round(i)) + 1 for i in xyz2irc(tuple(x + maxWidth_mm / 2 for x in center_xyz), self.origin_xyz, self.vxSize_xyz, self.direction_tup)]

        for axis in range(3):
            if ct_start[axis] > ct_end[axis]:
                ct_start[axis], ct_end[axis] = ct_end[axis], ct_start[axis]

        pad_start = [0, 0, 0]
        pad_end = [ct_end[axis] - ct_start[axis] for axis in range(3)]
        # log.info([ct_end, ct_start, pad_end])
        chunk_ary = np.zeros(pad_end, dtype=np.float32)

        for axis in range(3):
            if ct_start[axis] < 0:
                pad_start[axis] = -ct_start[axis]
                ct_start[axis] = 0

            if ct_end[axis] > self.ary.shape[axis]:
                pad_end[axis] -= ct_end[axis] - self.ary.shape[axis]
                ct_end[axis] = self.ary.shape[axis]

        pad_slices = tuple(slice(s,e) for s, e in zip(pad_start, pad_end))
        ct_slices = tuple(slice(s,e) for s, e in zip(ct_start, ct_end))
        chunk_ary[pad_slices] = self.ary[ct_slices]

        return chunk_ary, center_irc
Ejemplo n.º 2
0
    def getRawCandidate(self, center_xyz, width_irc):
        center_irc = xyz2irc(center_xyz, self.origin_xyz, self.vxSize_xyz,
                             self.direction_a)

        slice_list = []
        for axis, center_val in enumerate(center_irc):
            start_ndx = int(round(center_val - width_irc[axis] / 2))
            end_ndx = int(start_ndx + width_irc[axis])

            assert center_val >= 0 and center_val < self.hu_a.shape[axis], repr(
                [
                    self.series_uid, center_xyz, self.origin_xyz,
                    self.vxSize_xyz, center_irc, axis
                ])

            if start_ndx < 0:
                # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
                #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
                start_ndx = 0
                end_ndx = int(width_irc[axis])

            if end_ndx > self.hu_a.shape[axis]:
                # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
                #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
                end_ndx = self.hu_a.shape[axis]
                start_ndx = int(self.hu_a.shape[axis] - width_irc[axis])

            slice_list.append(slice(start_ndx, end_ndx))

        ct_chunk = self.hu_a[tuple(slice_list)]

        return ct_chunk, center_irc
Ejemplo n.º 3
0
    def getRawCandidate(self, center_xyz, width_irc):
        center_irc = xyz2irc(
            center_xyz,
            self.origin_xyz,
            self.vxSize_xyz,
            self.direction_a,
        )#将候选结节坐标(xyz)转换为irc坐标

        slice_list = []
        
        #裁剪整个ct图像,提取出结节图像
        for axis, center_val in enumerate(center_irc):#center_irc是一个元组(i坐标的值,r的值,c的值)
            start_ndx = int(round(center_val - width_irc[axis]/2))#width_irc :图像的深度、高度、宽度
            end_ndx = int(start_ndx + width_irc[axis])

            assert center_val >= 0 and center_val < self.hu_a.shape[axis], repr([self.series_uid, center_xyz, self.origin_xyz, self.vxSize_xyz, center_irc, axis])
            
            #当如上做法导致所裁剪的小区域的起始坐标和结束坐标超出整个ct图像的边界时
            if start_ndx < 0:
                # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
                #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
                start_ndx = 0
                end_ndx = int(width_irc[axis])

            if end_ndx > self.hu_a.shape[axis]:
                # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
                #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
                end_ndx = self.hu_a.shape[axis]
                start_ndx = int(self.hu_a.shape[axis] - width_irc[axis])

            slice_list.append(slice(start_ndx, end_ndx))

        ct_chunk = self.hu_a[tuple(slice_list)]#([s,e],[],[])

        return ct_chunk, center_irc
Ejemplo n.º 4
0
    def getRawNodule(self, center_xyz, width_irc):
        center_irc = xyz2irc(center_xyz, self.origin_xyz, self.vxSize_xyz,
                             self.direction_tup)

        slice_list = []
        for axis, center_val in enumerate(center_irc):
            start_ndx = int(round(center_val - width_irc[axis] / 2))
            end_ndx = int(start_ndx + width_irc[axis])

            assert center_val >= 0 and center_val < self.hu_a.shape[axis], \
                repr([self.series_uid, center_xyz, self.origin_xyz,
                self.vxSize_xyz, center_irc, axis])

            if start_ndx < 0:
                start_ndx = 0
                end_ndx = int(width_irc[axis])

            if end_ndx > self.hu_a.shape[axis]:
                end_ndx = self.hu_a.shape[axis]
                start_ndx = int(self.hu_a.shape[axis] - width_irc[axis])

            slice_list.append(slice(start_ndx, end_ndx))

        ct_chunk = self.hu_a[tuple(slice_list)]

        return ct_chunk, center_irc
Ejemplo n.º 5
0
    def buildAnnotationMask(self, noduleInfo_list, threshold_hu=-500):
        boundingBox_a = np.zeros_like(self.hu_a, dtype=np.bool)

        for noduleInfo_tup in noduleInfo_list:
            center_irc = xyz2irc(noduleInfo_tup.center_xyz, self.origin_xyz,
                                 self.vxSize_xyz, self.direction_tup)
            ci = int(center_irc.index)
            cr = int(center_irc.row)
            cc = int(center_irc.col)
            radius = 2

            # Index
            ci_min = ci - radius
            ci_max = ci + radius
            try:
                while self.hu_a[ci_max, cr, cc] > threshold_hu and \
                        self.hu_a[ci_min, cr, cc] > threshold_hu:
                    ci_min -= 1
                    ci_max += 1
            except IndexError:
                ci_min += 1
                ci_max -= 1

            # Row
            cr_min = ci - radius
            cr_max = ci + radius
            try:
                while self.hu_a[ci, cr_max, cc] > threshold_hu and \
                        self.hu_a[ci, cr_max, cc] > threshold_hu:
                    cr_min -= 1
                    cr_max += 1
            except IndexError:
                cr_min += 1
                cr_max -= 1

            # Column
            cc_min = ci - radius
            cc_max = ci + radius
            try:
                while self.hu_a[ci, cr, cc_max] > threshold_hu and \
                        self.hu_a[ci, cr, cc_min] > threshold_hu:
                    cc_min -= 1
                    cc_max += 1
            except IndexError:
                cc_min += 1
                cc_max -= 1

            slice_tup = (
                slice(ci - radius, ci + radius + 1),
                slice(ci - radius, ci + radius + 1),
                slice(ci - radius, ci + radius + 1),
            )
            boundingBox_a[slice_tup] = True

        thresholded_a = boundingBox_a & (self.hu_a > threshold_hu)
        # Every "False" next to a "True" is converted to "True".
        # iterations=2 means that the process is repeted two times.
        mask_a = morph.binary_dilation(thresholded_a, iterations=2)

        return mask_a, thresholded_a, boundingBox_a
Ejemplo n.º 6
0
	def getRawCandidate(self, center_xyz, width_irc):
		'''
		The getRawNodule function takes the center expressed in the patient coordinate system (X,Y,Z) as well as width in voxels,
		And returns a cubic chunk of CT as well as the center of the candidate converted to array coordinates.
		'''
		center_irc = xyz2irc(
			center_xyz,
			self.origin_xyz,
			self.vxSize-xyz,
			self.direction_a)

		slice_list = []
		for axis, center_val in enumerate(center_irc):
			start_ndx = int(round(center_val - width_irc[axis]/2))
			end_ndx = int(start_ndx + width_irc[axis])

			assert center_val >= 0 and center_val < self.hu_a.shape[axis], repr([self.series_uid, center_xyz, self.origin_xyz, self.vxSize_xyz, center_irc, axis])

			if start_ndx < 0:
				#Crop outside of CT array
				start_ndx = 0
				end_ndx = int(width_irc[axis])

			if end_ndx > self.hu_array.shape[axis]:
				#Crop outside of CT array
				end_ndx = self.hu_array.shape[axis]
				start_ndx = int(self.hu_array.shape[axis] - width_irc[axis])

			slice_list.append(slice(start_ndx, end_ndx))

		ct_chunk = self.hu_array[tuple(slice_list)]

		return ct_chunk, center_irc
Ejemplo n.º 7
0
    def buildAnnotationMask(self, positiveInfo_list, threshold_hu=-700):
        boundingBox_a = np.zeros_like(self.hu_a, dtype=np.bool)

        for candidateInfo_tup in positiveInfo_list:
            center_irc = xyz2irc(
                candidateInfo_tup.center_xyz,
                self.origin_xyz,
                self.vxSize_xyz,
                self.direction_a,
            )
            ci = int(center_irc.index)
            cr = int(center_irc.row)
            cc = int(center_irc.col)

            index_radius = 2
            try:
                while (
                    self.hu_a[ci + index_radius, cr, cc] > threshold_hu
                    and self.hu_a[ci - index_radius, cr, cc] > threshold_hu
                ):
                    index_radius += 1
            except IndexError:
                index_radius -= 1

            row_radius = 2
            try:
                while (
                    self.hu_a[ci, cr + row_radius, cc] > threshold_hu
                    and self.hu_a[ci, cr - row_radius, cc] > threshold_hu
                ):
                    row_radius += 1
            except IndexError:
                row_radius -= 1

            col_radius = 2
            try:
                while (
                    self.hu_a[ci, cr, cc + col_radius] > threshold_hu
                    and self.hu_a[ci, cr, cc - col_radius] > threshold_hu
                ):
                    col_radius += 1
            except IndexError:
                col_radius -= 1

            # assert index_radius > 0, repr([candidateInfo_tup.center_xyz, center_irc, self.hu_a[ci, cr, cc]])
            # assert row_radius > 0
            # assert col_radius > 0

            boundingBox_a[
                ci - index_radius : ci + index_radius + 1,
                cr - row_radius : cr + row_radius + 1,
                cc - col_radius : cc + col_radius + 1,
            ] = True

        mask_a = boundingBox_a & (self.hu_a > threshold_hu)

        return mask_a
Ejemplo n.º 8
0
    def buildAnnotationMask(self, noduleInfo_list, threshold_hu = -500):
        boundingBox_a = np.zeros_like(self.hu_a, dtype=np.bool)

        for noduleInfo_tup in noduleInfo_list:
            center_irc = xyz2irc(
                noduleInfo_tup.center_xyz,
                self.origin_xyz,
                self.vxSize_xyz,
                self.direction_tup,
            )
            ci = int(center_irc.index)
            cr = int(center_irc.row)
            cc = int(center_irc.col)

            index_radius = 2
            try:
                while self.hu_a[ci + index_radius, cr, cc] > threshold_hu and \
                        self.hu_a[ci - index_radius, cr, cc] > threshold_hu:
                    index_radius += 1
            except IndexError:
                index_radius -= 1

            row_radius = 2
            try:
                while self.hu_a[ci, cr + row_radius, cc] > threshold_hu and \
                        self.hu_a[ci, cr - row_radius, cc] > threshold_hu:
                    row_radius += 1
            except IndexError:
                row_radius -= 1

            col_radius = 2
            try:
                while self.hu_a[ci, cr, cc + col_radius] > threshold_hu and \
                        self.hu_a[ci, cr, cc - col_radius] > threshold_hu:
                    col_radius += 1
            except IndexError:
                col_radius -= 1

            # assert index_radius > 0, repr([noduleInfo_tup.center_xyz, center_irc, self.hu_a[ci, cr, cc]])
            # assert row_radius > 0
            # assert col_radius > 0


            slice_tup = (
                slice(ci - index_radius, ci + index_radius + 1),
                slice(cr - row_radius, cr + row_radius + 1),
                slice(cc - col_radius, cc + row_radius + 1),
            )
            boundingBox_a[slice_tup] = True

        thresholded_a = boundingBox_a & (self.hu_a > threshold_hu)
        mask_a = morph.binary_dilation(thresholded_a, iterations=2)

        return mask_a, thresholded_a, boundingBox_a
Ejemplo n.º 9
0
    def logImages(self, epoch_ndx, train_dl, test_dl):
        for mode_str, dl in [('trn', train_dl), ('tst', test_dl)]:
            for i, series_uid in enumerate(sorted(dl.dataset.series_list)[:12]):
                ct = getCt(series_uid)
                noduleInfo_tup = (ct.malignantInfo_list or ct.benignInfo_list)[0]
                center_irc = xyz2irc(noduleInfo_tup.center_xyz, ct.origin_xyz, ct.vxSize_xyz, ct.direction_tup)

                sample_tup = dl.dataset[(series_uid, int(center_irc.index))]
                input_tensor = sample_tup[0].unsqueeze(0)
                label_tensor = sample_tup[1].unsqueeze(0)

                input_devtensor = input_tensor.to(self.device)
                label_devtensor = label_tensor.to(self.device)

                prediction_devtensor = self.model(input_devtensor)
                prediction_ary = prediction_devtensor.to('cpu').detach().numpy()

                image_ary = np.zeros((512, 512, 3), dtype=np.float32)
                image_ary[:,:,:] = (input_tensor[0,2].numpy().reshape((512,512,1))) * 0.25
                image_ary[:,:,0] += prediction_ary[0,0] * 0.5
                image_ary[:,:,1] += prediction_ary[0,1] * 0.25
                # image_ary[:,:,2] += prediction_ary[0,2] * 0.5

                # log.debug([image_ary.__array_interface__['typestr']])

                # image_ary = (image_ary * 255).astype(np.uint8)

                # log.debug([image_ary.__array_interface__['typestr']])

                writer = getattr(self, mode_str + '_writer')
                try:
                    writer.add_image('{}/{}_pred'.format(mode_str, i), image_ary, self.totalTrainingSamples_count, dataformats='HWC')
                except:
                    log.debug([image_ary.shape, image_ary.dtype])
                    raise

                if epoch_ndx == 1:
                    label_ary = label_tensor.numpy()

                    image_ary = np.zeros((512, 512, 3), dtype=np.float32)
                    image_ary[:,:,:] = (input_tensor[0,2].numpy().reshape((512,512,1))) * 0.25
                    image_ary[:,:,0] += label_ary[0,0] * 0.5
                    image_ary[:,:,1] += label_ary[0,1] * 0.25
                    image_ary[:,:,2] += (input_tensor[0,-1].numpy() - (label_ary[0,0].astype(np.bool) | label_ary[0,1].astype(np.bool))) * 0.25

                    # log.debug([image_ary.__array_interface__['typestr']])

                    image_ary = (image_ary * 255).astype(np.uint8)

                    # log.debug([image_ary.__array_interface__['typestr']])

                    writer = getattr(self, mode_str + '_writer')
                    writer.add_image('{}/{}_label'.format(mode_str, i), image_ary, self.totalTrainingSamples_count, dataformats='HWC')
Ejemplo n.º 10
0
    def getScaledInputChunk(self, center_xyz, width_mm, voxels_int):
        center_irc = xyz2irc(center_xyz, self.origin_xyz, self.vxSize_xyz, self.direction_tup)

        ct_start = [int(round(i)) for i in xyz2irc(tuple(x - width_mm/2 for x in center_xyz), self.origin_xyz, self.vxSize_xyz, self.direction_tup)]
        ct_end = [int(round(i)) + 1 for i in xyz2irc(tuple(x + width_mm/2 for x in center_xyz), self.origin_xyz, self.vxSize_xyz, self.direction_tup)]

        for axis in range(3):
            if ct_start[axis] > ct_end[axis]:
                ct_start[axis], ct_end[axis] = ct_end[axis], ct_start[axis]

        pad_start = [0, 0, 0]
        pad_end = [ct_end[axis] - ct_start[axis] for axis in range(3)]
        # log.info([ct_end, ct_start, pad_end])
        pad_ary = np.zeros(pad_end, dtype=np.float32)

        for axis in range(3):
            if ct_start[axis] < 0:
                pad_start[axis] = -ct_start[axis]
                ct_start[axis] = 0

            if ct_end[axis] > self.ary.shape[axis]:
                pad_end[axis] -= ct_end[axis] - self.ary.shape[axis]
                ct_end[axis] = self.ary.shape[axis]

        pad_slices = tuple(slice(s,e) for s, e in zip(pad_start, pad_end))
        ct_slices = tuple(slice(s,e) for s, e in zip(ct_start, ct_end))
        pad_ary[pad_slices] = self.ary[ct_slices]

        try:
            zoom_seq = tuple(voxels_int/pad_ary.shape[axis] for axis in range(3))
        except:
            log.error([ct_end, ct_start, pad_end, center_irc, center_xyz, width_mm, self.vxSize_xyz])
            raise

        chunk_ary = scipy.ndimage.zoom(pad_ary, zoom_seq, order=1)

        # log.info("chunk_ary.shape {}".format([chunk_ary.shape, pad_ary.shape, zoom_seq, voxels_int]))

        return chunk_ary, center_irc
Ejemplo n.º 11
0
    def buildAnnotationMask(self, noduleInfo_list, threshold_gcc = 0.5):
        boundingBox_ary = np.zeros_like(self.ary, dtype=np.bool)

        for noduleInfo_tup in noduleInfo_list:
            center_irc = xyz2irc(noduleInfo_tup.center_xyz, self.origin_xyz, self.vxSize_xyz, self.direction_tup)
            center_index = int(center_irc.index)
            center_row = int(center_irc.row)
            center_col = int(center_irc.col)

            index_radius = 2
            try:
                while self.ary[center_index + index_radius, center_row, center_col] > threshold_gcc and \
                            self.ary[center_index - index_radius, center_row, center_col] > threshold_gcc:
                    index_radius += 1
            except IndexError:
                index_radius -= 1

            row_radius = 2
            try:
                while self.ary[center_index, center_row + row_radius, center_col] > threshold_gcc and \
                            self.ary[center_index, center_row - row_radius, center_col] > threshold_gcc:
                    row_radius += 1
            except IndexError:
                row_radius -= 1

            col_radius = 2
            try:
                while self.ary[center_index, center_row, center_col + col_radius] > threshold_gcc and \
                            self.ary[center_index, center_row, center_col - col_radius] > threshold_gcc:
                    col_radius += 1
            except IndexError:
                col_radius -= 1

            # assert index_radius > 0, repr([noduleInfo_tup.center_xyz, center_irc, self.ary[center_index, center_row, center_col]])
            # assert row_radius > 0
            # assert col_radius > 0


            slice_tup = (
                slice(
                    # max(0, center_index - index_radius),
                    center_index - index_radius,
                    center_index + index_radius + 1,
                ),
                slice(
                    # max(0, center_row - row_radius),
                    center_row - row_radius,
                    center_row + row_radius + 1,
                ),
                slice(
                    # max(0, center_col - col_radius),
                    center_col - col_radius,
                    center_col + row_radius + 1,
                ),
            )

            boundingBox_ary[slice_tup] = True

        thresholded_ary = boundingBox_ary & (self.ary > threshold_gcc)
        mask_ary = scipy.ndimage.morphology.binary_dilation(thresholded_ary, iterations=2)

        return mask_ary, thresholded_ary, boundingBox_ary