예제 #1
0
    def ocr(self, job_id):
        all_config = recognize.getConfig()

        job_data = tools.loadJobData(job_id)
        logging.debug('Load job data: %s' % str(job_data))

        cur_config = all_config[job_data['type']]
        logging.debug('Load recognize config: %s' % str(cur_config))

        img = cv2.imread(job_data['file'], cv2.IMREAD_UNCHANGED)

        res_orc = []

        for roi_name in cur_config['roi']:
            roi_config = cur_config['roi'][roi_name]

            if roi_config.get('hide', False):
                logging.info('Ignore roi [%s] because it is hidden' % roi_name)
                continue

            roi_orc_data = {
                'name': roi_name,
                'value': None,
            }

            if roi_config.get('ocr', True):
                roi_value_type = roi_config.get('type', 'text')

                if roi_value_type not in tools.OCR_TYPE_MAPPING:
                    logging.error('ROI Type %s not exist, skipped' %
                                  roi_value_type)
                    continue

                roi_img, roi_path = tools.createRoi2(img, roi_name, roi_config,
                                                     job_id + '/step3')
                roi_orc_data['value'] = tools.callOcr(roi_img,
                                                      job_id + '/step3',
                                                      roi_config)

                logging.info('OCR for roi [%s, type=%s] = %s' %
                             (roi_name, roi_value_type, roi_orc_data['value']))

            res_orc.append(roi_orc_data)

        return res_orc
예제 #2
0
    def extractImage(self, job_id):
        all_config = recognize.getConfig()

        job_data = tools.loadJobData(job_id)
        logging.debug('Load job data: %s' % str(job_data))

        cur_config = all_config[job_data['type']]
        logging.debug('Load recognize config: %s' % str(cur_config))

        img = cv2.imread(job_data['file'], cv2.IMREAD_UNCHANGED)
        img_roi_draw = img.copy()

        res_images = []

        for roi_name in cur_config['roi']:
            roi_config = cur_config['roi'][roi_name]

            if roi_config.get('hide', False):
                logging.info('Ignore roi [%s] because it is hidden' % roi_name)
                continue

            logging.info('Create roi [%s] = %s' % (roi_name, str(roi_config)))
            roi_img, roi_path = tools.createRoi2(img, roi_name, roi_config,
                                                 job_id + '/step2')
            tools.drawRoi(img_roi_draw, roi_config)

            res_images.append({
                'name': roi_name,
                'x': roi_config['x'],
                'y': roi_config['y'],
                'w': roi_config['w'],
                'h': roi_config['h'],
                'file': roi_path,
            })

        tools.writeImageJob(img_roi_draw, job_id + '/step2', '1 draw roi')

        return {'images': res_images}
예제 #3
0
app = Flask(__name__)


@app.route('/health')
def heath_check():
    return 'OK'


api = Api(app)

api.add_resource(DetectType2.DetectType2Api, '/api/detect_invoice')
api.add_resource(ExtractImage2.ExtractImage2Api, '/api/extract_image')
api.add_resource(Ocr2.OCR2Api, '/api/ocr')
api.add_resource(CompressImage.CompressImageApi, '/api/compress_image')

logging.debug('Load Recongize Config: %s' % str(recognize.getConfig()))

def getVaildImgFileList():
    rootDir = r"/home/hello/work/OCRServer/inv_img/"
    lstValidImgFile = []
    bExitLoop = False
    for parent, dirnames, filenames in os.walk(rootDir):
        for filename in filenames:
            if filename.endswith(".jpg"):
                imgFile = os.path.join(parent,filename)
                lstValidImgFile.append(imgFile)
                #if len(lstValidImgFile) > 50:
                #    bExitLoop = True;
                #    break;
        if bExitLoop:
            break;
예제 #4
0
    def detectType(self, image, job_id):
        config = recognize.getConfig()

        ############################################
        # 1. find matched type and config
        ############################################
        grey = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        logging.info("Start match...")

        # if multi-type is matched, using highest match rate as the matched one.
        # TODO: highest match rate is not preciseness, should be improved here

        cur_match_type_name = None
        cur_match_rate = -1
        cur_match_M = None
        cur_polygons = None

        logging.debug("Start match feature")

        sift = cv2.xfeatures2d.SIFT_create()
        ori_kp, ori_des = sift.detectAndCompute(grey, None)

        #logging.debug("config is %s" % str(config))

        for type_name in config:
            match_rate, detect_img, perspective_M, polygons = self.matchAndImageCut(sift, grey,
                                                                                    ori_kp, ori_des,
                                                                                    type_name,
                                                                                    config[type_name]['feature'],
                                                                                    config[type_name]['image'],
                                                                                    job_id)

            if match_rate > 0:
                logging.info("[%s] is matched, rate = %s" % (type_name, match_rate))
                tools.writeImageJob(detect_img, str(job_id) + '/step1', '1 match [%s] detect' % type_name)
                # tools.writeImageJob(cut_img, job_id + '/step1', '1 match [%s] cut' % type_name)

                if match_rate > cur_match_rate:
                    cur_match_rate = match_rate
                    cur_match_type_name = type_name
                    cur_match_M = perspective_M
                    cur_polygons = polygons

            else:
                logging.info("[%s] is not matched" % type_name)

        logging.debug("End match feature")

        print("cur_polygons =>", polygons)

        if not cur_match_type_name:
            logging.info("No feature matched")
            return self.make_error_response(image)

        logging.info("Match [%s] at %.2f%%, M=%s" % (cur_match_type_name, cur_match_rate, cur_match_M))

        ############################################
        # 2. rotate the image
        # TODO: should support different kinds of rotate/perspective way.
        ############################################
        cur_config = config[cur_match_type_name]
        perspective_img = None

        if cur_config['rotate'] == 'perspective':
            #print("image shape =>", image.shape)
	        #print("cur_config[image_w] =>", cur_config['image']['w'], 
		  #"cur_config[image_h] =>", cur_config['image']['h'])
            perspective_img = cv2.warpPerspective(image, cur_match_M,
                                                  (cur_config['image']['w'], cur_config['image']['h']),
                                                  flags=cv2.INTER_LANCZOS4)

	        #print("perspective_img.shape =>", perspective_img.shape)
            tools.writeImageJob(perspective_img, str(job_id) + '/step1', '2 perspective-%s' % cur_match_type_name)
        else:
            logging.error('rotate %s is not supported' % cur_config['rotate'])
            return self.make_error_response(image)

        # draw all roi in img
        perspective_draw_img = perspective_img.copy()
        for roiName in cur_config['roi']:
            tools.drawRoi(perspective_draw_img, cur_config['roi'][roiName], (0, 0, 255))

        tools.writeImageJob(perspective_draw_img, str(job_id) + '/step1', '3 mark roi')

        ############################################
        # 3. extract the validate area
        ############################################
        validate_roi_names = cur_config['validate']['roi']

        for validate_roi_name in validate_roi_names:
            validate_roi_config = cur_config['roi'].get(validate_roi_name, None)

            if not validate_roi_config:
                logging.error('Validate ROI[%s] not exist in roi section' % validate_roi_name)

            validate_roi, validate_roi_path = tools.createRoi2(perspective_img, validate_roi_name, validate_roi_config,
                                                           str(job_id) + '/step1')
            #ocr_result = tools.callOcr(validate_roi, job_id + '/step1', validate_roi_config)

            #logging.info('Validate ROI OCR result = %s' % ocr_result)

        return
        ############################################
        # 4. create compress jpg image
        ############################################
        compress_path = tools.writeImageJob(perspective_img, str(job_id) + '/step1', 'compressd', quality='compress')
        normlize_path = tools.writeImageJob(perspective_img, str(job_id) + '/step1', 'normlized', quality='lossless')

        ############################################
        # 5. write to yaml
        ############################################
        data = {
            'file': normlize_path,
            'type': cur_match_type_name
        }

        tools.saveJobData(data, str(job_id))

        logging.info('Save to data.yaml: %s' % str(data))

        return {
            'ori_image': {
                # ori_w, ori_h is the origin image without any change (uploaded by wechat)
                'w': image.shape[1],
                'h': image.shape[0],
            },
            'normalize_image': {
                # w, h, file: normalized image (roate,resize, perspective)
                'w': int(perspective_img.shape[1]) if perspective_img is not None else None,
                'h': int(perspective_img.shape[0]) if perspective_img is not None else None,
                'file': compress_path,
                'extract_polygon': cur_polygons,
            },
            # the detected image type and its value based, the roi is based on normalized image
            # if not match, set None
            'type': {
                'name': cur_match_type_name,
                'desc': cur_config.get('name', cur_match_type_name),
                'value': orc_result,
                'roi': {
                    'x': validate_roi_config['x'],
                    'y': validate_roi_config['y'],
                    'w': validate_roi_config['w'],
                    'h': validate_roi_config['h'],
                    'file': validate_roi_path
                }
            }
        }