프로젝트

일반

사용자정보

개정판 c6ab5aaf

IDc6ab5aaf9646a41e3ccfc7a4b5de099f06771316
상위 e019d322
하위 3a7d7b10

함의성이(가) 4년 이상 전에 추가함

issue #663: detect blind flange

Change-Id: I816f6146c23b968c6c87179c763a07a613e09ba9

차이점 보기:

DTI_PID/DTI_PID/ConfigurationDialog.py
223 223
        self.ui.lineEditFlange.setText(configs[0].value) if 1 == len(configs) else \
224 224
        self.ui.lineEditFlange.setText('flange')
225 225

  
226
        configs = docData.getConfigs('Default', 'Blind')
227
        self.ui.lineEditBlind.setText(configs[0].value) if 1 == len(configs) else \
228
        self.ui.lineEditBlind.setText('blind flange')
229

  
226 230
        properties = docData.getLineProperties()
227 231
        if properties:
228 232
            for prop in properties:
......
1040 1044
            configs.append(Config('Text Recognition', 'White Single Text', self.ui.lineEditSingleText.text()))
1041 1045
            configs.append(Config('Text Recognition', 'Allowable Pair', self.ui.lineEditAllowablePair.text()))
1042 1046
            configs.append(Config('Default', 'Flange', self.ui.lineEditFlange.text()))
1047
            configs.append(Config('Default', 'Blind', self.ui.lineEditBlind.text()))
1043 1048
            configs.append(Config('Text Recognition', 'Page Segmentation Modes',
1044 1049
                                  str(self.ui.comboBoxPageSegmentationModes.currentIndex())))
1045 1050
            # Add Line Color Option - 2018.07.06 by kyouho
DTI_PID/DTI_PID/Configuration_UI.py
423 423
        self.gridLayout_40.setObjectName("gridLayout_40")
424 424
        self.gridLayout_39 = QtWidgets.QGridLayout()
425 425
        self.gridLayout_39.setObjectName("gridLayout_39")
426
        self.lineEditFlange = QtWidgets.QLineEdit(self.groupBoxSymbol)
427
        self.lineEditFlange.setObjectName("lineEditFlange")
428
        self.gridLayout_39.addWidget(self.lineEditFlange, 2, 1, 1, 1)
429
        self.label_52 = QtWidgets.QLabel(self.groupBoxSymbol)
430
        self.label_52.setObjectName("label_52")
431
        self.gridLayout_39.addWidget(self.label_52, 2, 0, 1, 1)
432
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
433
        self.gridLayout_39.addItem(spacerItem3, 2, 2, 1, 1)
426 434
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
427 435
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
428 436
        self.radioButtonDetectPackageYes = QtWidgets.QRadioButton(self.groupBoxSymbol)
......
439 447
        self.label_53 = QtWidgets.QLabel(self.groupBoxSymbol)
440 448
        self.label_53.setObjectName("label_53")
441 449
        self.gridLayout_39.addWidget(self.label_53, 1, 0, 1, 1)
442
        self.lineEditFlange = QtWidgets.QLineEdit(self.groupBoxSymbol)
443
        self.lineEditFlange.setObjectName("lineEditFlange")
444
        self.gridLayout_39.addWidget(self.lineEditFlange, 2, 1, 1, 1)
445
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
446
        self.gridLayout_39.addItem(spacerItem3, 2, 2, 1, 1)
447
        self.label_52 = QtWidgets.QLabel(self.groupBoxSymbol)
448
        self.label_52.setObjectName("label_52")
449
        self.gridLayout_39.addWidget(self.label_52, 2, 0, 1, 1)
450
        self.label_56 = QtWidgets.QLabel(self.groupBoxSymbol)
451
        self.label_56.setObjectName("label_56")
452
        self.gridLayout_39.addWidget(self.label_56, 3, 0, 1, 1)
453
        self.lineEditBlind = QtWidgets.QLineEdit(self.groupBoxSymbol)
454
        self.lineEditBlind.setObjectName("lineEditBlind")
455
        self.gridLayout_39.addWidget(self.lineEditBlind, 3, 1, 1, 1)
450 456
        self.gridLayout_40.addLayout(self.gridLayout_39, 0, 0, 1, 1)
451 457
        self.gridLayout_21.addWidget(self.groupBoxSymbol, 1, 1, 1, 1)
452 458
        self.tabWidget.addTab(self.Recognition2, "")
......
997 1003
        self.label_9.setText(_translate("ConfigurationDialog", "Length to Connect Line : "))
998 1004
        self.radioButtonGapNo.setText(_translate("ConfigurationDialog", "No"))
999 1005
        self.groupBoxSymbol.setTitle(_translate("ConfigurationDialog", "Symbol"))
1006
        self.label_52.setText(_translate("ConfigurationDialog", "Default Flange : "))
1000 1007
        self.radioButtonDetectPackageYes.setText(_translate("ConfigurationDialog", "Yes"))
1001 1008
        self.radioButtonDetectPackageNo.setText(_translate("ConfigurationDialog", "No"))
1002 1009
        self.label_53.setText(_translate("ConfigurationDialog", "Detect Inside Equipment Package : "))
1003
        self.label_52.setText(_translate("ConfigurationDialog", "Defualt Flange : "))
1010
        self.label_56.setText(_translate("ConfigurationDialog", "Default Blind Flange : "))
1004 1011
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.Recognition2), _translate("ConfigurationDialog", "Recognition"))
1005 1012
        self.groupBox_4.setTitle(_translate("ConfigurationDialog", "Note No Tag Rule"))
1006 1013
        self.checkBoxNoteNoSymbolName.setText(_translate("ConfigurationDialog", "Note No Symbol Name : "))
DTI_PID/DTI_PID/LineDetector.py
327 327
                        # calculate direction of connector
328 328
                        dx = connector.center()[0] - symbol.origin[0]
329 329
                        dy = connector.center()[1] - symbol.origin[1]
330
                    else:
331
                        dx, dy = direction.x(), direction.y()
332
                    # up to here
333

  
334
                    length = math.sqrt(dx * dx + dy * dy)
335
                    if length > 0:
330
                        length = math.sqrt(dx * dx + dy * dy)
331
                        if length <= 0:
332
                            continue
336 333
                        dx /= length
337 334
                        dy /= length
335
                    else:
336
                        dx, dy = direction.x(), direction.y()
337
                    # up to here                    
338 338

  
339 339
                        if abs(dx) < 0.1:  # vertical line
340 340
                            dir = [0, 1 if dy > 0 else -1]
DTI_PID/DTI_PID/RecognitionDialog.py
1244 1244
                
1245 1245
                # detect flange
1246 1246
                flange_list = []
1247
                blind_list = []
1247 1248
                
1248 1249
                print('flag3.9')
1249 1250
                configs = app_doc_data.getConfigs('Project', 'Operation')
......
1310 1311
                                if sym.conn_type:
1311 1312
                                    for index in range(len(sym.conn_type)):
1312 1313
                                        item = sym.connectors[index].connectedItem
1313
                                        if item and type(item) is QEngineeringLineItem:
1314
                                            #worker.detectFlangeOnPid(sym, app_doc_data.activeDrawing.image_origin, worker, app_doc_data._imgFilePath, app_doc_data)
1314
                                        if item and type(item) is QEngineeringLineItem and (sym.conn_type[index] == 'Secondary' or sym.conn_type[index] == 'Primary') \
1315
                                            and item.is_piping(True):
1315 1316
                                            point = worker.detectFlangeOnPid(sym, sym.connectors[index], item, app_doc_data.activeDrawing.image_origin)
1316 1317
                                            if point is not None:
1317 1318
                                                flange_list.append(point)
1318
                                                pass
1319

  
1320
                                        elif not item and (sym.conn_type[index] == 'Secondary' or sym.conn_type[index] == 'Primary'):
1321
                                            point = worker.detectFlangeOnPid(sym, sym.connectors[index], None, app_doc_data.activeDrawing.image_origin)
1322
                                            if point is not None:
1323
                                                blind_list.append(point)
1324

  
1319 1325
                    except Exception as ex:
1320 1326
                        message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
1321 1327
                                  f"{sys.exc_info()[-1].tb_lineno}"
......
1367 1373
                    # up to here
1368 1374
                print('flag4')
1369 1375
                worker.create_unknown_items(mainRes)
1370
                worker.add_detected_items_to_scene.emit(worker.scene, flange_list)
1376
                worker.add_detected_items_to_scene.emit(worker.scene, [flange_list, blind_list])
1371 1377
                worker.cond.wait(worker.mutex)
1372 1378

  
1373 1379
                # run preset
......
1477 1483
                if direction is None:
1478 1484
                    dx = connector.center()[0] - symbol.origin[0]
1479 1485
                    dy = connector.center()[1] - symbol.origin[1]
1486
                    length = math.sqrt(dx * dx + dy * dy)
1487
                    if length <= 0:
1488
                        continue
1489
                    dx /= length
1490
                    dy /= length
1480 1491
                else:
1481 1492
                    dx, dy = direction.x(), direction.y()
1482 1493

  
1483
                length = math.sqrt(dx * dx + dy * dy)
1484
                if length <= 0:
1485
                    continue
1486

  
1487
                dx /= length
1488
                dy /= length
1489

  
1490 1494
                _lines = None
1491 1495
                if abs(dx) < 0.1:
1492 1496
                    _lines =  horizontals
......
2408 2412
    # TODO: detect flange
2409 2413
    @staticmethod
2410 2414
    def detectFlangeOnPid(symbol, connector, line, image):
2411
        pt = connector.sceneConnectPoint
2415
        pt = connector.center()
2412 2416
        x = int(pt[0])
2413 2417
        y = int(pt[1])
2414 2418
        center_x = int(symbol.loc[0] + symbol.size[0] / 2)
2415 2419
        center_y = int(symbol.loc[1] + symbol.size[1] / 2)
2416
        line_center_x = int((line.start_point()[0] + line.end_point()[0]) / 2)
2417
        line_center_y = int((line.start_point()[1] + line.end_point()[1]) / 2)
2418 2420

  
2419 2421
        arrow = Arrow.NULL
2420
        if line.isHorizontal():
2421
            if center_x < line_center_x:
2422
                arrow = Arrow.RIGHT
2423
            else:
2424
                arrow = Arrow.LEFT
2425
        elif line.isVertical():
2426
            if center_y < line_center_y:
2427
                arrow = Arrow.DOWN
2428
            else:
2429
                arrow = Arrow.UP
2422
        if line:
2423
            line_center_x = int((line.start_point()[0] + line.end_point()[0]) / 2)
2424
            line_center_y = int((line.start_point()[1] + line.end_point()[1]) / 2)
2430 2425

  
2431
        if arrow is not Arrow.NULL:
2432
            result = Worker.detectFlangeOnPidArrow(symbol, x, y, arrow, image)
2426
            if line.isHorizontal():
2427
                if center_x < line_center_x:
2428
                    arrow = Arrow.RIGHT
2429
                else:
2430
                    arrow = Arrow.LEFT
2431
            elif line.isVertical():
2432
                if center_y < line_center_y:
2433
                    arrow = Arrow.DOWN
2434
                else:
2435
                    arrow = Arrow.UP
2436

  
2437
            if arrow is not Arrow.NULL:
2438
                result = Worker.detectFlangeOnPidArrow(symbol, x, y, arrow, image)
2439
                if result:
2440
                    return [x, y]
2441
        else:
2442
            _dir = [round(connector.dir().x()),  round(connector.dir().y())]
2443
            if abs(_dir[0]) == 1:
2444
                if _dir[0] > 0:
2445
                    arrow = Arrow.RIGHT
2446
                else:
2447
                    arrow = Arrow.LEFT
2448
            elif abs(_dir[1]) == 1:
2449
                if _dir[1] > 0:
2450
                    arrow = Arrow.DOWN
2451
                else:
2452
                    arrow = Arrow.UP
2453

  
2454
            result = Worker.detectFlangeBlindOnPid(x, y, arrow, image)
2433 2455
            if result:
2434 2456
                return [x, y]
2435 2457
           
2436 2458
        return None
2437 2459

  
2438 2460
    @staticmethod
2461
    def detectFlangeBlindOnPid(start_x, start_y, arrow, image):
2462
        loopRange = []
2463
        if arrow is Arrow.DOWN:
2464
            loopRange = range(start_y - 20, start_y + 40)
2465
        elif arrow is Arrow.UP:
2466
            loopRange = range(start_y + 20, start_y - 40, -1)
2467
        elif arrow is Arrow.LEFT:
2468
            loopRange = range(start_x + 20, start_x - 40, -1)
2469
        elif arrow is Arrow.RIGHT:
2470
            loopRange = range(start_x - 20, start_x + 40)
2471
        else:
2472
            return None
2473

  
2474
        find_forward = False
2475
        find_backward = False
2476
        find = None
2477
        # 검은색 점을 찾는 범위
2478
        search_length = 30
2479
        # Line 최소 Length
2480
        checkLineLength = 20
2481
        # Line 최대 Width
2482
        line_width = 18
2483
        # flange min length
2484
        flange_min = 30
2485
        # flange max length
2486
        flange_max = 50
2487
        # flange max width
2488
        flange_count_max = 10
2489

  
2490
        # 임시
2491
        temp_count = 0
2492
        find_list_x = []
2493
        find_list_y = []
2494
        for i in loopRange:
2495
            loop_find = False
2496
            for j in range(search_length):
2497
                width = 0
2498
                color_1 = 0
2499
                color_2 = 0
2500
                find_x = 0
2501
                find_y = 0
2502

  
2503
                if arrow is Arrow.DOWN or arrow is Arrow.UP:
2504
                    color_1 = image[i, start_x - j]
2505
                    color_2 = image[i, start_x + j]
2506
                    if int(color_1) is 0:
2507
                        width = Worker.getWidth(start_x - j, i, arrow, image)
2508
                        find_x = start_x - j
2509
                        find_y = i
2510
                    elif int(color_2) is 0:
2511
                        width = Worker.getWidth(start_x + j, i, arrow, image)
2512
                        find_x = start_x + j
2513
                        find_y = i
2514

  
2515
                elif arrow is Arrow.LEFT or arrow is Arrow.RIGHT:
2516
                    color_1 = image[start_y - j, i]
2517
                    color_2 = image[start_y + j, i]
2518
                    if int(color_1) is 0:
2519
                        width = Worker.getWidth(i, start_y - j, arrow, image)
2520
                        find_x = i
2521
                        find_y = start_y - j
2522
                    elif int(color_2) is 0:
2523
                        width = Worker.getWidth(i, start_y + j, arrow, image)
2524
                        find_x = i
2525
                        find_y = start_y + j
2526

  
2527
                if flange_min < width < flange_max:
2528
                    loop_find = True
2529
                    find_list_x.append(find_x)
2530
                    find_list_y.append(find_y)
2531
                    break
2532
                elif width > 0:
2533
                    break
2534

  
2535
            if loop_find:
2536
                if temp_count > flange_count_max:
2537
                    break
2538
                temp_count = temp_count + 1
2539
            elif 0 < temp_count < flange_count_max and width > 0:
2540
                continue
2541
            elif 0 < temp_count < flange_count_max and width == 0:
2542
                find_forward = True
2543
                break
2544
            else:
2545
                find_list_x.clear()
2546
                find_list_y.clear()
2547
                temp_count = 0
2548

  
2549
        if not find_forward:
2550
            return False
2551

  
2552
        # 임시
2553
        temp_count = 0
2554
        find_list_x = []
2555
        find_list_y = []
2556
        for i in reversed(loopRange):
2557
            loop_find = False
2558
            for j in range(search_length):
2559
                width = 0
2560
                color_1 = 0
2561
                color_2 = 0
2562
                find_x = 0
2563
                find_y = 0
2564

  
2565
                if arrow is Arrow.DOWN or arrow is Arrow.UP:
2566
                    color_1 = image[i, start_x - j]
2567
                    color_2 = image[i, start_x + j]
2568
                    if int(color_1) is 0:
2569
                        width = Worker.getWidth(start_x - j, i, arrow, image)
2570
                        find_x = start_x - j
2571
                        find_y = i
2572
                    elif int(color_2) is 0:
2573
                        width = Worker.getWidth(start_x + j, i, arrow, image)
2574
                        find_x = start_x + j
2575
                        find_y = i
2576

  
2577
                elif arrow is Arrow.LEFT or arrow is Arrow.RIGHT:
2578
                    color_1 = image[start_y - j, i]
2579
                    color_2 = image[start_y + j, i]
2580
                    if int(color_1) is 0:
2581
                        width = Worker.getWidth(i, start_y - j, arrow, image)
2582
                        find_x = i
2583
                        find_y = start_y - j
2584
                    elif int(color_2) is 0:
2585
                        width = Worker.getWidth(i, start_y + j, arrow, image)
2586
                        find_x = i
2587
                        find_y = start_y + j
2588

  
2589
                if flange_min < width < flange_max:
2590
                    loop_find = True
2591
                    find_list_x.append(find_x)
2592
                    find_list_y.append(find_y)
2593
                    break
2594

  
2595
            if loop_find:
2596
                if temp_count > flange_count_max:
2597
                    break
2598
                temp_count = temp_count + 1
2599
            elif 0 < temp_count < flange_count_max and width > 0:
2600
                continue
2601
            elif 0 < temp_count < flange_count_max and width == 0:
2602
                find_backward = True
2603
                break
2604
            else:
2605
                find_list_x.clear()
2606
                find_list_y.clear()
2607
                temp_count = 0
2608
        
2609
        if find_forward and find_backward:
2610
            return True
2611

  
2612
    @staticmethod
2439 2613
    def detectFlangeOnPidArrow(symbol, start_x, start_y, arrow, image):
2440 2614
        loopRange = []
2441 2615
        if arrow is Arrow.DOWN:
......
2460 2634
        flange_min = 30
2461 2635
        # flange max length
2462 2636
        flange_max = 50
2637
        # flange max width
2638
        flange_count_max = 10
2463 2639
        # 임시
2464 2640
        temp_count = 0
2465 2641
        find_list_x = []
......
2484 2660
                        width = Worker.getWidth(start_x + j, i, arrow, image)
2485 2661
                        find_x = start_x + j
2486 2662
                        find_y = i
2487
                    else:
2488
                        pass
2663

  
2489 2664
                elif arrow is Arrow.LEFT or arrow is Arrow.RIGHT:
2490 2665
                    color_1 = image[start_y - j, i]
2491 2666
                    color_2 = image[start_y + j, i]
......
2497 2672
                        width = Worker.getWidth(i, start_y + j, arrow, image)
2498 2673
                        find_x = i
2499 2674
                        find_y = start_y + j
2500
                    else:
2501
                        pass
2502
                else:
2503
                    pass
2504
                if width > 0 and width <= line_width and loop_find is False:
2505
                    find = True
2675

  
2676
                if 0 < width <= line_width:
2506 2677
                    loop_find = True
2507 2678
                    find_list_x.append(find_x)
2508 2679
                    find_list_y.append(find_y)
2509 2680
                    break
2510 2681

  
2511
            if find and loop_find:
2682
            if loop_find:
2512 2683
                if temp_count > checkLineLength:
2684
                    find = True
2513 2685
                    break
2514 2686
                temp_count = temp_count + 1
2515 2687
            else:
2516 2688
                find_list_x.clear()
2517 2689
                find_list_y.clear()
2518 2690
                temp_count = 0
2519
                find = False
2520 2691
        
2521 2692
        if find:
2522 2693
            count = 0
......
2552 2723
                else:
2553 2724
                    pass
2554 2725

  
2555
            if 0 < flange_count < 10 and find_white:
2726
            if 0 < flange_count < flange_count_max and find_white:
2556 2727
                crop_image = None
2557 2728
                x = find_list_x[0] - (int(symbol.loc[0]) - int(symbol.size[0]) - 1)
2558 2729
                y = find_list_y[0] - (int(symbol.loc[1]) - int(symbol.size[1]) - 1)
......
3911 4082
            if instrument == 1:
3912 4083
                configs = app_doc_data.getConfigs('Default', 'Flange')
3913 4084
                flange_name = configs[0].value if 1 == len(configs) else 'flange'
3914
                for flange in flanges:
4085
                for flange in flanges[0]:
3915 4086
                    svg = QtImageViewer.createSymbolObject(flange_name)
3916 4087
                    if svg:
3917 4088
                        QtImageViewer.matchSymbolToLine(scene, svg, QPointF(flange[0], flange[1]), strict=True, auto=True)
3918 4089

  
4090
                configs = app_doc_data.getConfigs('Default', 'Blind')
4091
                flange_name = configs[0].value if 1 == len(configs) else 'blind flange'
4092
                for flange in flanges[1]:
4093
                    svg = QtImageViewer.createSymbolObject(flange_name)
4094
                    if svg:
4095
                        QtImageViewer.matchSymbolToLine(scene, svg, QPointF(flange[0], flange[1]), strict=False, auto=True)
4096

  
3919 4097
                for unknown in app_doc_data.unknowns + app_doc_data.lineIndicators:
3920 4098
                    scene.addItem(unknown)
3921 4099

  
DTI_PID/DTI_PID/UI/Configuration.ui
919 919
         <layout class="QGridLayout" name="gridLayout_40">
920 920
          <item row="0" column="0">
921 921
           <layout class="QGridLayout" name="gridLayout_39">
922
            <item row="2" column="1">
923
             <widget class="QLineEdit" name="lineEditFlange"/>
924
            </item>
925
            <item row="2" column="0">
926
             <widget class="QLabel" name="label_52">
927
              <property name="text">
928
               <string>Default Flange : </string>
929
              </property>
930
             </widget>
931
            </item>
932
            <item row="2" column="2">
933
             <spacer name="horizontalSpacer_7">
934
              <property name="orientation">
935
               <enum>Qt::Horizontal</enum>
936
              </property>
937
              <property name="sizeHint" stdset="0">
938
               <size>
939
                <width>40</width>
940
                <height>20</height>
941
               </size>
942
              </property>
943
             </spacer>
944
            </item>
922 945
            <item row="1" column="1">
923 946
             <layout class="QHBoxLayout" name="horizontalLayout_10">
924 947
              <item>
......
950 973
              </property>
951 974
             </widget>
952 975
            </item>
953
            <item row="2" column="1">
954
             <widget class="QLineEdit" name="lineEditFlange"/>
955
            </item>
956
            <item row="2" column="2">
957
             <spacer name="horizontalSpacer_7">
958
              <property name="orientation">
959
               <enum>Qt::Horizontal</enum>
960
              </property>
961
              <property name="sizeHint" stdset="0">
962
               <size>
963
                <width>40</width>
964
                <height>20</height>
965
               </size>
966
              </property>
967
             </spacer>
968
            </item>
969
            <item row="2" column="0">
970
             <widget class="QLabel" name="label_52">
976
            <item row="3" column="0">
977
             <widget class="QLabel" name="label_56">
971 978
              <property name="text">
972
               <string>Defualt Flange : </string>
979
               <string>Default Blind Flange : </string>
973 980
              </property>
974 981
             </widget>
975 982
            </item>
983
            <item row="3" column="1">
984
             <widget class="QLineEdit" name="lineEditBlind"/>
985
            </item>
976 986
           </layout>
977 987
          </item>
978 988
         </layout>
......
1957 1967
 </connections>
1958 1968
 <buttongroups>
1959 1969
  <buttongroup name="buttonGroup_3"/>
1970
  <buttongroup name="buttonGroup_2"/>
1971
  <buttongroup name="buttonGroup"/>
1960 1972
  <buttongroup name="buttonGroup_8"/>
1961
  <buttongroup name="buttonGroup_4"/>
1962 1973
  <buttongroup name="buttonGroup_5"/>
1963
  <buttongroup name="buttonGroup_7"/>
1964 1974
  <buttongroup name="buttonGroup_6"/>
1965
  <buttongroup name="buttonGroup_2"/>
1966
  <buttongroup name="buttonGroup"/>
1975
  <buttongroup name="buttonGroup_4"/>
1967 1976
  <buttongroup name="buttonGroup_9"/>
1977
  <buttongroup name="buttonGroup_7"/>
1968 1978
 </buttongroups>
1969 1979
</ui>

내보내기 Unified diff