コード例 #1
0
ファイル: utils.py プロジェクト: saeedghsh/arrangement
def unbound_traits(trait_list):
    '''
    this method takes a list of traits and converts them as follow:
    ray -> line
    segment -> line
    line -> line
    arc -> circle
    circle -> circle
    '''

    for idx, trait in enumerate(trait_list):

        if isinstance(trait, (trts.SegmentModified, trts.RayModified)):
            # if the trait is (ray v segment) convert to line
            trait = trts.LineModified(args=(trait.obj.p1, trait.obj.p2))

        elif isinstance(trait, trts.ArcModified):
            # if the trait is (arc) convert to circle
            trait = trts.Circle(args=(trait.obj.center, trait.obj.radius))

        else:
            # the trait is either line or circle
            # no need to adjust the trait
            pass

        # insertig the corrected trait back in the list
        trait_list[idx] = trait

    return trait_list
コード例 #2
0
    def load_traits_from_file(self):

        if self.data['image_name'] is not '':
            dir_suggestion = self.data['image_name'].split('.')[0]
            file_name = PySide.QtGui.QFileDialog.getOpenFileName(
                None, 'Open File', dir_suggestion)[0]
        else:
            file_name = PySide.QtGui.QFileDialog.getOpenFileName()[0]

        if file_name is u'':
            print('\t WARNING: no file was selected. file load aborted...')
            return None

        file_ext = file_name.split('.')[-1]

        # method exits if the file extension is not supported
        if not (file_ext in ['yaml', 'YAML', 'yml', 'YML', 'svg', 'SVG']):
            print('\t WARNING: only yaml and svg files are supported')
            return None

        # convert svg to yaml and load the yaml file
        if file_ext in ['svg', 'SVG']:
            file_name = arr_utils.svg_to_ymal(
                file_name, convert_segment_2_infinite_line=False)
            print(
                '\t NOTE: svg file converted to yaml, and the yaml file will be loaded'
            )

        print('todo: arrangement has a yaml loader, use that instead?')
        stream = open(file_name, 'r')
        data = yaml.load(stream)

        traits = []
        if 'lines' in data.keys():
            for l in data['lines']:
                if len(l) == 4:  #[x1,y1,x2,y2]
                    traits += [
                        trts.LineModified(args=(sym.Point(l[0], l[1]),
                                                sym.Point(l[2], l[3])))
                    ]
                elif len(l) == 3:  #[x1,y1,slope]
                    traits += [
                        trts.LineModified(args=(sym.Point(l[0], l[1]), l[2]))
                    ]

        if 'segments' in data.keys():
            for s in data['segments']:
                traits += [
                    trts.SegmentModified(args=(sym.Point(s[0], s[1]),
                                               sym.Point(s[2], s[3])))
                ]

        if 'rays' in data.keys():
            for r in data['rays']:
                traits += [
                    trts.RayModified(args=(sym.Point(r[0], r[1]),
                                           sym.Point(r[2], r[3])))
                ]

        if 'circles' in data.keys():
            for c in data['circles']:
                traits += [
                    trts.CircleModified(args=(sym.Point(c[0], c[1]), c[2]))
                ]

        if 'arcs' in data.keys():
            for a in data['arcs']:
                traits += [
                    trts.ArcModified(args=(sym.Point(a[0], a[1]), a[2],
                                           (a[3], a[4])))
                ]

        # copying loaded data into self.trait_list
        if self.ui.radioButton_load_traits_overwrite.isChecked():
            self.trait_list = traits
        else:
            self.trait_list.extend(traits)

        # updating trait list listWidget
        self.update_trait_list_listWidget()

        # updating the canvas
        self.traits_visualization_canvas.clear_axes()
        self.plot_traits_visualization_canvas()
コード例 #3
0
    def find_lines_with_radiography(self):
        ''''''

        ### get the appropriate input image
        if self.ui.radioButton_radiography_source_origin.isChecked():
            # using original image
            image = self.data['image']

        elif self.ui.radioButton_radiography_source_binary.isChecked():
            # thresholding to binary
            string = self.ui.textEdit_binary_thresholding.toPlainText()
            [thr1, thr2] = [float(param) for param in string.split(',')]
            if [thr1, thr2] != self.img_prc['binary thresholding']:
                self.img_prc['binary thresholding'] = [thr1, thr2]
                self.update_binary_image()
            image = self.data['binary']

        elif self.ui.radioButton_radiography_source_edge.isChecked():
            # using edge image
            string = self.ui.textEdit_canny_setting.toPlainText()
            [thr1, thr2,
             apt_size] = [float(param) for param in string.split(',')]
            if [thr1, thr2, apt_size] != self.img_prc['canny setting']:
                self.update_edge_image()
            image = self.data['edges']

        if len(self.data['dominant_orientation']) > 0:

            ### fetching setting for sinogram peak detection
            string = self.ui.textEdit_sinogram_peak_detection_setting.toPlainText(
            )
            [refWin, minDist,
             minVal] = [float(param) for param in string.split(',')]

            ### radiography
            # flipud: why? I'm sure it won't work otherwise, but dont know why
            # It should happen in both "find_dominant_orientations" & "find_grid_lines"
            image = np.flipud(image)
            imgcenter = (
                image.shape[1] / 2,  # cols == x
                image.shape[0] / 2)  # rows == y

            orientations = self.data['dominant_orientation']
            sinog_angles = orientations - np.pi / 2  # in radian
            sinograms = skimage.transform.radon(image,
                                                theta=sinog_angles * 180 /
                                                np.pi)  #, circle=True)
            sinogram_center = len(sinograms.T[0]) / 2

            # ########## debug-mode
            # row, col = 1,1
            # fig, axes = plt.subplots(row, col, figsize=(20,12))
            # for singo in sinograms.T:
            #     axes.plot(singo)
            # fig.show()
            # ##########

            lines = []
            for (orientation, sinog_angle,
                 sinogram) in zip(orientations, sinog_angles, sinograms.T):
                # Find peaks in sinogram:
                peakind = utilities.FindPeaks(sinogram,
                                              CWT=False,
                                              cwt_range=(1, 8, 1),
                                              Refine_win=int(refWin),
                                              MinPeakDist=int(minDist),
                                              MinPeakVal=minVal,
                                              Polar=False)

                # line's distance to the center of the image
                dist = np.array(peakind) - sinogram_center

                pts_0 = [(imgcenter[0] + d * np.cos(sinog_angle),
                          imgcenter[1] + d * np.sin(sinog_angle))
                         for d in dist]

                pts_1 = [(point[0] + np.cos(orientation),
                          point[1] + np.sin(orientation)) for point in pts_0]

                lines += [
                    trts.LineModified(args=(sym.Point(p0[0], p0[1]),
                                            sym.Point(p1[0], p1[1])))
                    for (p0, p1) in zip(pts_0, pts_1)
                ]

            self.trait_buffer = lines
            # self.trait_buffer += lines
            self.plot_traits_visualization_canvas()
            print('\t found {:d} lines'.format(len(lines)))
        else:
            print(
                '\t WARNING: no dominant orientation is available, so... goodluck'
            )
コード例 #4
0
    def construct_trait_from_annotation(self):
        ''' '''

        # not enough point for any trait, unless I add points as trait (later)
        if len(self.annotation) < 2:

            # if only one point, make a line from p0 and orientation
            if len(self.data['dominant_orientation']) == 1:
                if self.ui.radioButton_man_annotate_line.isChecked():

                    p0 = self.annotation[-1]
                    p1 = [
                        p0[0] + np.cos(self.data['dominant_orientation'][0]),
                        p0[1] + np.sin(self.data['dominant_orientation'][0])
                    ]
                    # print (p0,self.data['dominant_orientation'][0],p1 )
                    l_trait = trts.LineModified(args=(sym.Point(p0[0], p0[1]),
                                                      sym.Point(p1[0], p1[1])))

                    self.trait_buffer.append(l_trait)
                    self.traits_visualization_canvas.draw_trait_line(
                        l_trait, 'r', '--')
                    self.reset_trait_annotation()

            # print ('\t WARNING: not enough point for the selected trait class')
            return

        if self.ui.radioButton_man_annotate_line.isChecked():
            # considering only the last two elements of the annotation list
            p0, p1 = self.annotation[-2], self.annotation[-1]
            l_trait = trts.LineModified(args=(sym.Point(p0[0], p0[1]),
                                              sym.Point(p1[0], p1[1])))
            self.trait_buffer.append(l_trait)
            self.traits_visualization_canvas.draw_trait_line(l_trait)

        elif self.ui.radioButton_man_annotate_segment.isChecked():
            # considering only the last two elements of the annotation list
            p0, p1 = self.annotation[-2], self.annotation[-1]
            s_trait = trts.SegmentModified(args=(sym.Point(p0[0], p0[1]),
                                                 sym.Point(p1[0], p1[1])))
            self.trait_buffer.append(s_trait)
            self.traits_visualization_canvas.draw_trait_segment(s_trait)

        elif self.ui.radioButton_man_annotate_ray.isChecked():
            # considering only the last two elements of the annotation list
            p0, p1 = self.annotation[-2], self.annotation[-1]
            r_trait = trts.RayModified(args=(sym.Point(p0[0], p0[1]),
                                             sym.Point(p1[0], p1[1])))
            self.trait_buffer.append(r_trait)
            self.traits_visualization_canvas.draw_trait_ray(r_trait)

        elif self.ui.radioButton_man_annotate_circle.isChecked():

            if len(self.annotation) == 2:
                # if 2 points are given, the 1st is the center and 2nd is on the perimeter
                [xc, yc], [x1, y1] = self.annotation[0], self.annotation[1]
                rc = np.sqrt((xc - x1)**2 + (yc - y1)**2)
            elif len(self.annotation) > 2:
                # if 3 points are given, they are all considered on the perimeter
                # http://mathworld.wolfram.com/Circle.html
                [x1, y1], [x2, y2], [x3, y3] = self.annotation[
                    -3], self.annotation[-2], self.annotation[-1]
                a = np.array([[x1, y1, 1], [x2, y2, 1], [x3, y3, 1]])
                d = np.array([[x1**2 + y1**2, y1, 1], [x2**2 + y2**2, y2, 1],
                              [x3**2 + y3**2, y3, 1]])
                e = np.array([[x1**2 + y1**2, x1, 1], [x2**2 + y2**2, x2, 1],
                              [x3**2 + y3**2, x3, 1]])
                f = np.array([[x1**2 + y1**2, x1, y1], [x2**2 + y2**2, x2, y2],
                              [x3**2 + y3**2, x3, y3]])
                a, d, e, f = det(a), -det(d), det(e), -det(f)
                xc, yc = -d / (2 * a), -e / (2 * a)
                rc = np.sqrt(((d**2 + e**2) / (4 * (a**2))) - (f / a))

            c_trait = trts.CircleModified(args=(sym.Point(xc, yc), rc))
            self.trait_buffer.append(c_trait)
            self.traits_visualization_canvas.draw_trait_circle(c_trait)

        elif self.ui.radioButton_man_annotate_arc.isChecked():

            if len(self.annotation) <= 2:
                print(
                    '\t WARNING: need at least and only 3 points to estimate an arc'
                )
            else:
                [x1, y1], [x2, y2], [
                    x3, y3
                ] = self.annotation[0], self.annotation[1], self.annotation[2]
                a = np.array([[x1, y1, 1], [x2, y2, 1], [x3, y3, 1]])
                d = np.array([[x1**2 + y1**2, y1, 1], [x2**2 + y2**2, y2, 1],
                              [x3**2 + y3**2, y3, 1]])
                e = np.array([[x1**2 + y1**2, x1, 1], [x2**2 + y2**2, x2, 1],
                              [x3**2 + y3**2, x3, 1]])
                f = np.array([[x1**2 + y1**2, x1, y1], [x2**2 + y2**2, x2, y2],
                              [x3**2 + y3**2, x3, y3]])
                a, d, e, f = det(a), -det(d), det(e), -det(f)
                xc, yc = -d / (2 * a), -e / (2 * a)
                rc = np.sqrt(((d**2 + e**2) / (4 * (a**2))) - (f / a))

                # screw_up : t1,t2 \in [-pi,pi]
                # in CCW order, the 1st pt is start, 2nd pt is on the perimeter and 3rd pt is the end
                # but ArcModified will modify the theta values anyway, so a good chance of screw_up here
                # so I will impose the restriction on the user to maintain the order and I will correct
                # the values here so that t1< t2
                t1, t2 = np.arctan2(y1 - yc,
                                    x1 - xc), np.arctan2(y3 - yc, x3 - xc)
                if t1 > t2:
                    t2 += 2 * np.pi  # or t1 -= 2*np.pi ?

                a_trait = trts.ArcModified(args=(sym.Point(xc, yc), rc, (t1,
                                                                         t2)))
                self.trait_buffer.append(a_trait)
                self.traits_visualization_canvas.draw_trait_circle(a_trait)

        self.reset_trait_annotation()
コード例 #5
0
    def load_traits_from_file(self):

        file_name = PySide.QtGui.QFileDialog.getOpenFileName()[0]
        file_ext = file_name.split('.')[-1]

        # method exits if the file extension is not supported
        if not (file_ext in ['yaml', 'YAML', 'yml', 'YML', 'svg', 'SVG']):
            print('\t WARNING: only yaml and svg files are supported')
            return None

        # convert svg to yaml and load the yaml file
        if file_ext in ['svg', 'SVG']:
            file_name = mSGVp.svg_to_ymal(
                file_name, convert_segment_2_infinite_line=False)
            print(
                '\t NOTE: svg file converted to yaml, and the yaml file will be loaded'
            )

        stream = open(file_name, 'r')
        data = yaml.load(stream)

        traits = []

        if 'lines' in data.keys():
            for l in data['lines']:
                if len(l) == 4:  #[x1,y1,x2,y2]
                    traits += [
                        trts.LineModified(args=(sym.Point(l[0], l[1]),
                                                sym.Point(l[2], l[3])))
                    ]
                elif len(l) == 3:  #[x1,y1,slope]
                    traits += [
                        trts.LineModified(args=(sym.Point(l[0], l[1]), l[2]))
                    ]

        if 'segments' in data.keys():
            for s in data['segments']:
                traits += [
                    trts.SegmentModified(args=(sym.Point(s[0], s[1]),
                                               sym.Point(s[2], s[3])))
                ]

        if 'rays' in data.keys():
            for r in data['rays']:
                traits += [
                    trts.RayModified(args=(sym.Point(r[0], r[1]),
                                           sym.Point(r[2], r[3])))
                ]

        if 'circles' in data.keys():
            for c in data['circles']:
                traits += [
                    trts.CircleModified(args=(sym.Point(c[0], c[1]), c[2]))
                ]

        if 'arcs' in data.keys():
            for a in data['arcs']:
                traits += [
                    trts.ArcModified(args=(sym.Point(a[0], a[1]), a[2],
                                           (a[3], a[4])))
                ]

        # copying loaded data into self.trait_list
        if self.ui.radioButton_load_traits_overwrite.isChecked():
            self.trait_list = traits
        else:
            self.trait_list.extend(traits)

        # updating the canvas with traits
        self.plot_traits()