Beispiel #1
0
    def convert_colors_to_labels(self, target_classes, labels_colors):
        """
		Convert the label image to a numpy array with the labels' values.
		"""

        label_w = self.label_image.width()
        label_h = self.label_image.height()

        imglbl = utils.qimageToNumpyArray(self.label_image)

        num_classes = len(target_classes)

        # class 0 --> background
        self.labels = np.zeros((label_h, label_w), dtype='int64')
        for i, cl in enumerate(target_classes):
            class_colors = labels_colors.get(cl)
            if class_colors is None:
                if cl == "Background":
                    class_colors = [0, 0, 0]
                else:
                    class_colors = [255, 255, 255]
            idx = np.where((imglbl[:, :, 0] == class_colors[0])
                           & (imglbl[:, :, 1] == class_colors[1])
                           & (imglbl[:, :, 2] == class_colors[2]))
            self.labels[idx] = i + 1
Beispiel #2
0
	def classFrequenciesOnDataset(self, labels_dir, target_classes, labels_colors):
		"""
		Returns the frequencies of the target classes on the given dataset.
        """

		num_classes = len(target_classes)

		image_label_names = [x for x in glob.glob(os.path.join(labels_dir, '*.png'))]

		total_pixels = 0
		counters = np.zeros(num_classes, dtype='float')
		for label_name in image_label_names:

			image_label = QImage(label_name)
			# image_label = image_label.convertToFormat(QImage.Format_RGB32)
			label_w = image_label.width()
			label_h = image_label.height()
			total_pixels += label_w * label_h
			imglbl = utils.qimageToNumpyArray(image_label)

			# class 0 --> background
			labelsint = np.zeros((label_h, label_w), dtype='int64')
			for i, cl in enumerate(target_classes):
				class_colors = labels_colors[cl]
				idx = np.where((imglbl[:, :, 0] == class_colors[0]) & (imglbl[:, :, 1] == class_colors[1]) & (
							imglbl[:, :, 2] == class_colors[2]))
				labelsint[idx] = i + 1

			for i in range(len(target_classes)):
				counters[i] += float(np.count_nonzero(labelsint == i + 1))

		freq = counters / float(total_pixels)
		print(freq)
Beispiel #3
0
    def import_label_map(self,
                         filename,
                         labels_info,
                         w_target,
                         h_target,
                         create_holes=False):
        """
        It imports a label map and create the corresponding blobs.
        The label map is rescaled such that it coincides with the reference map.
        """

        qimg_label_map = QImage(filename)
        qimg_label_map = qimg_label_map.convertToFormat(QImage.Format_RGB32)

        if w_target > 0 and h_target > 0:
            qimg_label_map = qimg_label_map.scaled(w_target, h_target,
                                                   Qt.IgnoreAspectRatio,
                                                   Qt.FastTransformation)

        label_map = utils.qimageToNumpyArray(qimg_label_map)
        label_map = label_map.astype(np.int32)

        # RGB -> label code association (ok, it is a dirty trick but it saves time..)
        label_coded = label_map[:, :, 0] + (label_map[:, :, 1] << 8) + (
            label_map[:, :, 2] << 16)

        labels = measure.label(label_coded, connectivity=1)

        too_much_small_area = 50
        region_big = None

        created_blobs = []
        for region in measure.regionprops(labels):
            if region.area > too_much_small_area:
                id = len(self.seg_blobs)
                blob = Blob(region, 0, 0, self.getFreeId())

                # assign class
                row = region.coords[0, 0]
                col = region.coords[0, 1]
                color = label_map[row, col]

                for label_name in labels_info.keys():
                    c = labels_info[label_name]
                    if c[0] == color[0] and c[1] == color[1] and c[2] == color[
                            2]:
                        blob.class_name = label_name
                        blob.class_color = c
                        break
                if create_holes or blob.class_name is not 'Empty':
                    created_blobs.append(blob)

        return created_blobs
Beispiel #4
0
    def import_label_map(self, filename, reference_map):
        """
        It imports a label map and create the corresponding blobs.
        The label map is rescaled such that it coincides with the reference map.
        """

        qimg_label_map = QImage(filename)
        qimg_label_map = qimg_label_map.convertToFormat(QImage.Format_RGB32)

        w = reference_map.width()
        h = reference_map.height()
        qimg_label_map = qimg_label_map.scaled(w, h, Qt.IgnoreAspectRatio,
                                               Qt.SmoothTransformation)

        label_map = utils.qimageToNumpyArray(qimg_label_map)
        label_map = label_map.astype(np.int32)

        # RGB -> label code association (ok, it is a dirty trick but it saves time..)
        label_coded = label_map[:, :, 0] + (label_map[:, :, 1] << 8) + (
            label_map[:, :, 2] << 16)

        labels = measure.label(label_coded, connectivity=1)

        label_info = Labels()

        too_much_small_area = 10
        region_big = None

        created_blobs = []
        for region in measure.regionprops(labels):
            if region.area > too_much_small_area:
                id = len(self.seg_blobs)
                blob = Blob(region, 0, 0, id + 1)

                # assign class
                row = region.coords[0, 0]
                col = region.coords[0, 1]
                color = label_map[row, col]

                index = label_info.searchColor(color)

                if index >= 0:

                    blob.class_name = label_info.getClassName(index)
                    blob.class_color = label_info.getColorByIndex(index)

                    created_blobs.append(blob)

        return created_blobs
Beispiel #5
0
    def import_label_map(self, filename, reference_map):
        """
        It imports a label map and create the corresponding blobs.
        The label map is rescaled such that it coincides with the reference map.
        """

        qimg_label_map = QImage(filename)
        qimg_label_map = qimg_label_map.convertToFormat(QImage.Format_RGB32)

        w = reference_map.width()
        h = reference_map.height()
        qimg_label_map = qimg_label_map.scaled(w, h, Qt.IgnoreAspectRatio,
                                               Qt.SmoothTransformation)

        label_map = utils.qimageToNumpyArray(qimg_label_map)
        label_map = label_map.astype(np.int32)

        # RGB -> label code association (ok, it is a dirty trick but it saves time..)
        label_coded = label_map[:, :, 0] + (label_map[:, :, 1] << 8) + (
            label_map[:, :, 2] << 16)

        labels = measure.label(label_coded, connectivity=1)

        too_much_small_area = 1000
        region_big = None

        created_blobs = []
        for region in measure.regionprops(labels):
            if region.area > too_much_small_area:
                id = len(self.seg_blobs)
                blob = Blob(region, 0, 0, self.progressive_id)
                self.progressive_id += 1

                # assign class
                row = region.coords[0, 0]
                col = region.coords[0, 1]
                color = label_map[row, col]

                for label_name in self.labels_info.keys():
                    c = self.labels_info[label_name]
                    if c[0] == color[0] and c[1] == color[1] and c[2] == color[
                            2]:
                        blob.class_name = label_name
                        blob.class_color = c
                        break

                created_blobs.append(blob)

        return created_blobs
Beispiel #6
0
    def splitBlob(self, map, blob, seeds):

        seeds = np.asarray(seeds)
        seeds = seeds.astype(int)
        mask = blob.getMask()
        box = blob.bbox
        cropimg = utils.cropQImage(map, box)
        cropimgnp = rgb2gray(utils.qimageToNumpyArray(cropimg))

        edges = sobel(cropimgnp)

        # x,y
        seeds_matrix = np.zeros_like(mask)

        size = 40
        #
        for i in range(0, seeds.shape[0]):
            #y,x
            seeds_matrix[seeds[i, 1] - box[0] - (size - 1):seeds[i, 1] -
                         box[0] + (size - 1), seeds[i, 0] - box[1] -
                         (size - 1):seeds[i, 0] - box[1] + (size - 1)] = 1

        distance = ndi.distance_transform_edt(mask)
        # distance = ndi.distance_transform_edt(cropimg)
        seeds_matrix = seeds_matrix > 0.5
        markers = ndi.label(seeds_matrix)[0]
        # labels = watershed(-distance, markers, mask=mask)
        labels = watershed((-distance + 100 * edges) / 2, markers, mask=mask)
        created_blobs = []
        for region in measure.regionprops(labels):
            b = Blob(region, box[1], box[0], self.progressive_id)
            self.progressive_id += 1
            b.class_color = blob.class_color
            b.class_name = blob.class_name
            created_blobs.append(b)

        return created_blobs
Beispiel #7
0
    def __init__(self, map, annotations, blob, x, y, parent=None):
        super(QtCrackWidget, self).__init__(parent)

        self.setStyleSheet("background-color: rgb(60,60,65); color: white")

        self.qimg_cropped = utils.cropQImage(map, blob.bbox)
        arr = utils.qimageToNumpyArray(self.qimg_cropped)
        self.input_arr = rgb2gray(arr) * 255
        self.tolerance = 20
        self.annotations = annotations
        self.blob = blob
        self.xmap = x
        self.ymap = y
        self.qimg_crack = QImage(self.qimg_cropped.width(),
                                 self.qimg_cropped.height(),
                                 QImage.Format_RGB32)
        self.qimg_crack.fill(qRgb(0, 0, 0))

        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setFixedWidth(400)
        self.setFixedHeight(400)

        SLIDER_WIDTH = 200
        IMAGEVIEWER_SIZE = 300  # SIZE x SIZE

        self.sliderTolerance = QSlider(Qt.Horizontal)
        self.sliderTolerance.setFocusPolicy(Qt.StrongFocus)
        self.sliderTolerance.setMinimumWidth(SLIDER_WIDTH)
        self.sliderTolerance.setMinimum(1)
        self.sliderTolerance.setMaximum(100)
        self.sliderTolerance.setValue(self.tolerance)
        self.sliderTolerance.setTickInterval(5)
        self.sliderTolerance.setAutoFillBackground(True)
        self.sliderTolerance.valueChanged.connect(self.sliderToleranceChanged)

        self.lblTolerance = QLabel("Tolerance: 20")
        self.lblTolerance.setAutoFillBackground(True)
        str = "Tolerance {}".format(self.tolerance)
        self.lblTolerance.setText(str)

        layoutTolerance = QHBoxLayout()
        layoutTolerance.addWidget(self.lblTolerance)
        layoutTolerance.addWidget(self.sliderTolerance)

        self.viewerplus = QtImageViewerPlus()
        self.viewerplus.disableScrollBars()
        self.viewerplus.setFixedWidth(IMAGEVIEWER_SIZE)
        self.viewerplus.setFixedHeight(IMAGEVIEWER_SIZE)

        self.btnCancel = QPushButton("Cancel")
        self.btnCancel.setAutoFillBackground(True)

        self.btnApply = QPushButton("Apply")
        self.btnApply.setAutoFillBackground(True)

        layoutButtons = QHBoxLayout()
        layoutButtons.addWidget(self.btnCancel)
        layoutButtons.addWidget(self.btnApply)

        layoutV = QVBoxLayout()
        layoutV.addLayout(layoutTolerance)
        layoutV.addWidget(self.viewerplus)
        layoutV.addLayout(layoutButtons)
        layoutV.setSpacing(10)
        self.setLayout(layoutV)

        self.viewerplus.setImage(self.qimg_cropped)
        self.preview()

        self.setAutoFillBackground(True)

        self.setWindowTitle("Crack")
        self.setWindowFlags(Qt.Window | Qt.CustomizeWindowHint
                            | Qt.WindowTitleHint)
Beispiel #8
0
    def run(self, img_map, TILE_SIZE, AGGREGATION_WINDOW_SIZE, AGGREGATION_STEP):
        """

        :param TILE_SIZE: Base tile. This corresponds to the INPUT SIZE of the network.
        :param AGGREGATION_WINDOW_SIZE: Size of the sub-windows to consider for the aggregation.
        :param AGGREGATION_STEP: Step, in pixels, to calculate the different scores.
        :return:
        """

        # create a temporary folder to store the processing
        temp_dir = "temp"
        if not os.path.exists(temp_dir):
            os.mkdir(temp_dir)

        # prepare for running..
        STEP_SIZE = AGGREGATION_WINDOW_SIZE

        W = img_map.width()
        H = img_map.height()

        # top, left, width, height
        working_area = [0, 0, W, H]

        wa_top = working_area[0]
        wa_left = working_area[1]
        wa_width = working_area[2]
        wa_height = working_area[3]

        if wa_top < AGGREGATION_STEP:
            wa_top = AGGREGATION_STEP

        if wa_left < AGGREGATION_STEP:
            wa_left = AGGREGATION_STEP

        if wa_left + wa_width >= W - AGGREGATION_STEP:
            wa_width = W - AGGREGATION_STEP - wa_left - 1

        if wa_top + wa_height >= H - AGGREGATION_STEP:
            wa_height = H - AGGREGATION_STEP - wa_top - 1

        tile_cols = int(wa_width / AGGREGATION_WINDOW_SIZE) + 1
        tile_rows = int(wa_height / AGGREGATION_WINDOW_SIZE) + 1

        if torch.cuda.is_available():
            device = torch.device("cuda")
            self.net.to(device)
            torch.cuda.synchronize()

        self.net.eval()

        # classification (per-tiles)
        tiles_number = tile_rows * tile_cols

        self.processing_step = 0
        self.total_processing_steps = 19 * tiles_number

        for row in range(tile_rows):

            if self.flagStopProcessing is True:
                break

            for col in range(tile_cols):

                if self.flagStopProcessing is True:
                    break

                scores = np.zeros((9, self.nclasses, TILE_SIZE, TILE_SIZE))

                k = 0
                for i in range(-1,2):
                    for j in range(-1,2):

                        top = wa_top - AGGREGATION_STEP + row * STEP_SIZE + i * AGGREGATION_STEP
                        left = wa_left - AGGREGATION_STEP + col * STEP_SIZE + j * AGGREGATION_STEP
                        cropimg = utils.cropQImage(img_map, [top, left, TILE_SIZE, TILE_SIZE])
                        img_np = utils.qimageToNumpyArray(cropimg)

                        img_np = img_np.astype(np.float32)
                        img_np = img_np / 255.0

                        # H x W x C --> C x H x W
                        img_np = img_np.transpose(2, 0, 1)

                        # Normalization (average subtraction)
                        img_np[0] = img_np[0] - self.average_norm[0]
                        img_np[1] = img_np[1] - self.average_norm[1]
                        img_np[2] = img_np[2] - self.average_norm[2]

                        with torch.no_grad():

                            img_tensor = torch.from_numpy(img_np)
                            input = img_tensor.unsqueeze(0)

                            if torch.cuda.is_available():
                                input = input.to(device)

                            outputs = self.net(input)

                            scores[k] = outputs[0].cpu().numpy()
                            k = k + 1

                            self.processing_step += 1
                            self.updateProgress.emit( (100.0 * self.processing_step) / self.total_processing_steps )
                            QCoreApplication.processEvents()


                if self.flagStopProcessing is True:
                    break

                # preds_avg, preds_bayesian = self.aggregateScores(scores, tile_sz=TILE_SIZE,
                #                                     center_window_size=AGGREGATION_WINDOW_SIZE, step=AGGREGATION_STEP)

                preds_avg = self.aggregateScores(scores, tile_sz=TILE_SIZE,
                                                     center_window_size=AGGREGATION_WINDOW_SIZE, step=AGGREGATION_STEP)

                values_t, predictions_t = torch.max(torch.from_numpy(preds_avg), 0)
                preds = predictions_t.cpu().numpy()

                resimg = np.zeros((preds.shape[0], preds.shape[1], 3), dtype='uint8')

                for label_index in range(self.nclasses):
                    resimg[preds == label_index, :] = self.label_colors[label_index]

                tilename = str(row) + "_" + str(col) + ".png"
                filename = os.path.join(temp_dir, tilename)
                utils.rgbToQImage(resimg).save(filename)

                self.processing_step += 1
                self.updateProgress.emit( (100.0 * self.processing_step) / self.total_processing_steps )
                QCoreApplication.processEvents()

        # put tiles together
        qimglabel = QImage(W, H, QImage.Format_RGB32)

        xoffset = 0
        yoffset = 0

        painter = QPainter(qimglabel)

        for r in range(tile_rows):
            for c in range(tile_cols):
                tilename = str(r) + "_" + str(c) + ".png"
                filename = os.path.join(temp_dir, tilename)
                qimg = QImage(filename)

                xoffset = wa_left + c * AGGREGATION_WINDOW_SIZE
                yoffset = wa_top + r * AGGREGATION_WINDOW_SIZE

                cut = False
                W_prime = wa_width
                H_prime = wa_height

                if xoffset + AGGREGATION_WINDOW_SIZE > wa_left + wa_width - 1:
                    W_prime = wa_width + wa_left - xoffset - 1
                    cut = True

                if yoffset + AGGREGATION_WINDOW_SIZE > wa_top + wa_height - 1:
                    H_prime = wa_height + wa_top - yoffset - 1
                    cut = True

                if cut is True:
                    qimg2 = qimg.copy(0, 0, W_prime, H_prime)
                    painter.drawImage(xoffset, yoffset, qimg2)
                else:
                    painter.drawImage(xoffset, yoffset, qimg)

        # detach the qimglabel otherwise the Qt EXPLODES when memory is free
        painter.end()

        labelfile = os.path.join(temp_dir, "labelmap.png")
        qimglabel.save(labelfile)

        torch.cuda.empty_cache()
        del self.net
        self.net = None
Beispiel #9
0
    def run(self,
            TILE_SIZE,
            AGGREGATION_WINDOW_SIZE,
            AGGREGATION_STEP,
            save_scores=False):
        """
        :param TILE_SIZE: Base tile. This corresponds to the INPUT SIZE of the network.
        :param AGGREGATION_WINDOW_SIZE: Size of the center window considered for the aggregation.
        :param AGGREGATION_STEP: Step, in pixels, to calculate the different scores.
        :return:
        """

        # create a temporary folder to store the processing
        if not os.path.exists(self.temp_dir):
            os.mkdir(self.temp_dir)

        # prepare for running..
        DELTA_CROP = int((TILE_SIZE - AGGREGATION_WINDOW_SIZE) / 2)
        tile_cols = int(self.wa_width / AGGREGATION_WINDOW_SIZE) + 1
        tile_rows = int(self.wa_height / AGGREGATION_WINDOW_SIZE) + 1

        if torch.cuda.is_available():
            device = torch.device("cuda")
            self.net.to(device)
            torch.cuda.synchronize()

        self.net.eval()

        # classification (per-tiles)
        tiles_number = tile_rows * tile_cols

        self.processing_step = 0
        self.total_processing_steps = 19 * tiles_number

        for row in range(tile_rows):

            if self.flagStopProcessing is True:
                break

            for col in range(tile_cols):

                if self.flagStopProcessing is True:
                    break

                scores = np.zeros((9, self.nclasses, TILE_SIZE, TILE_SIZE))

                k = 0
                for i in range(-1, 2):
                    for j in range(-1, 2):

                        top = self.wa_top - DELTA_CROP + row * AGGREGATION_WINDOW_SIZE + i * AGGREGATION_STEP
                        left = self.wa_left - DELTA_CROP + col * AGGREGATION_WINDOW_SIZE + j * AGGREGATION_STEP
                        tileimg = utils.cropQImage(
                            self.input_image,
                            [top, left, TILE_SIZE, TILE_SIZE])
                        img_np = utils.qimageToNumpyArray(tileimg)

                        img_np = img_np.astype(np.float32)
                        img_np = img_np / 255.0

                        # H x W x C --> C x H x W
                        img_np = img_np.transpose(2, 0, 1)

                        # Normalization (average subtraction)
                        img_np[0] = img_np[0] - self.average_norm[0]
                        img_np[1] = img_np[1] - self.average_norm[1]
                        img_np[2] = img_np[2] - self.average_norm[2]

                        with torch.no_grad():

                            img_tensor = torch.from_numpy(img_np)
                            input = img_tensor.unsqueeze(0)

                            if torch.cuda.is_available():
                                input = input.to(device)

                            outputs = self.net(input)

                            scores[k] = outputs[0].cpu().numpy()
                            k = k + 1

                            self.processing_step += 1
                            self.updateProgress.emit(
                                (100.0 * self.processing_step) /
                                self.total_processing_steps)
                            QCoreApplication.processEvents()

                if self.flagStopProcessing is True:
                    break

                preds_avg = self.aggregateScores(
                    scores,
                    tile_sz=TILE_SIZE,
                    center_window_size=AGGREGATION_WINDOW_SIZE,
                    step=AGGREGATION_STEP)

                values_t, predictions_t = torch.max(
                    torch.from_numpy(preds_avg), 0)
                preds = predictions_t.cpu().numpy()

                resimg = np.zeros((preds.shape[0], preds.shape[1], 3),
                                  dtype='uint8')
                for label_index in range(self.nclasses):
                    resimg[preds ==
                           label_index, :] = self.label_colors[label_index]

                tilename = str(row) + "_" + str(col) + ".png"
                filename = os.path.join(self.temp_dir, tilename)
                utils.rgbToQImage(resimg).save(filename)

                if save_scores is True:
                    tilename = str(row) + "_" + str(col) + ".dat"
                    filename = os.path.join(self.temp_dir, tilename)
                    fileobject = open(filename, 'wb')
                    pkl.dump(preds_avg, fileobject)
                    fileobject.close()

                self.processing_step += 1
                self.updateProgress.emit((100.0 * self.processing_step) /
                                         self.total_processing_steps)
                QCoreApplication.processEvents()

        self.assembleTiles(tile_rows,
                           tile_cols,
                           AGGREGATION_WINDOW_SIZE,
                           ass_scores=save_scores)
        torch.cuda.empty_cache()
        del self.net
        self.net = None
Beispiel #10
0
    def segmentation(self):

        # compute bbox of scribbles (working area)
        bboxes = []
        for i, curve in enumerate(self.scribbles.points):
            bbox = Mask.pointsBox(curve, int(self.scribbles.size[i] / 2))
            bboxes.append(bbox)
        working_area = Mask.jointBox(bboxes)

        if working_area[0] < 0:
            working_area[0] = 0

        if working_area[1] < 0:
            working_area[1] = 0

        if working_area[0] + working_area[3] > self.viewerplus.img_map.height(
        ) - 1:
            working_area[3] = self.viewerplus.img_map.height(
            ) - 1 - working_area[0]

        if working_area[1] + working_area[2] > self.viewerplus.img_map.width(
        ) - 1:
            working_area[2] = self.viewerplus.img_map.width(
            ) - 1 - working_area[1]

        crop_img = utils.cropQImage(self.viewerplus.img_map, working_area)
        crop_imgnp = utils.qimageToNumpyArray(crop_img)

        # create markers
        mask = np.zeros((working_area[3], working_area[2], 3), dtype=np.int32)

        color_codes = dict()
        counter = 1
        for i, curve in enumerate(self.scribbles.points):

            col = self.scribbles.label[i].fill
            b = col[2]
            g = col[1]
            r = col[0]
            color = (b, g, r)

            color_code = b + 256 * g + 65536 * r
            color_key = str(color_code)
            if color_codes.get(color_key) is None:
                name = self.scribbles.label[i].name
                color_codes[color_key] = (counter, name)
                counter = counter + 1

            curve = np.int32(curve)

            curve[:, 0] = curve[:, 0] - working_area[1]
            curve[:, 1] = curve[:, 1] - working_area[0]

            curve = curve.reshape((-1, 1, 2))
            mask = cv2.polylines(mask,
                                 pts=[curve],
                                 isClosed=False,
                                 color=color,
                                 thickness=self.scribbles.size[i],
                                 lineType=cv2.LINE_8)

        mask = np.uint8(mask)

        markers = np.zeros((working_area[3], working_area[2]), dtype='int32')
        for label in self.scribbles.label:
            col = label.fill
            b = col[2]
            g = col[1]
            r = col[0]
            color_code = b + 256 * g + 65536 * r
            color_key = str(color_code)

            idx = np.where((mask[:, :, 0] == b) & (mask[:, :, 1] == g)
                           & (mask[:, :, 2] == r))
            (value, name) = color_codes[color_key]
            markers[idx] = value

        # markers = np.int32(255*rgb2gray(mask))
        # markersprint = 255*rgb2gray(mask)
        markersprint = markers
        cv2.imwrite('mask.png', markersprint)

        # watershed segmentation
        segmentation = cv2.watershed(crop_imgnp, markers)
        segmentation = filters.median(segmentation, disk(5), mode="mirror")
        cv2.imwrite('segmentation.png', segmentation)

        # the result of the segmentation must be converted into labels again
        lbls = measure.label(segmentation)

        blobs = []
        for region in measure.regionprops(lbls):
            blob = Blob(region, working_area[1], working_area[0],
                        self.viewerplus.annotations.getFreeId())
            color_index = segmentation[region.coords[0][0],
                                       region.coords[0][1]]
            data = list(color_codes.items())
            index = 0
            for i in range(len(data)):
                (color_code, t) = data[i]
                if t[0] == color_index:
                    color_code = int(color_code)
                    r = int(color_code / 65536)
                    g = int(int(color_code - r * 65536) / 256)
                    b = int(color_code - r * 65536 - g * 256)
                    color = [r, g, b]
                    name = t[1]
                    break

            blob.class_color = color
            blob.class_name = name

            blobs.append(blob)

        return blobs