Parcourir la source

Merge branch 'dev' of http://192.168.136.99:3000/servers/ASJServer into dev

zhangdongming il y a 3 ans
Parent
commit
de36d45b27
4 fichiers modifiés avec 195 ajouts et 273 suppressions
  1. 82 257
      Controller/AiController.py
  2. 7 1
      Controller/DetectControllerV2.py
  3. 1 0
      Model/models.py
  4. 105 15
      Object/MergePic.py

+ 82 - 257
Controller/AiController.py

@@ -41,12 +41,12 @@ from Object.ETkObject import ETkObject
 from pyfcm import FCMNotification
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, APNS_MODE, APNS_CONFIG, BASE_DIR, \
-    JPUSH_CONFIG, FCM_CONFIG, OAUTH_ACCESS_TOKEN_SECRET
+    JPUSH_CONFIG, FCM_CONFIG, OAUTH_ACCESS_TOKEN_SECRET, DETECT_PUSH_DOMAINS
 from Controller.CheckUserData import DataValid
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
     Unused_Uid_Meal, UIDMainUser, UserModel, PromotionRuleModel, VideoPlaybackTimeModel, CloudLogModel, CouponModel, \
-    AiStoreMeal, AiService, UidSetModel, Ai_Push_Info, iotdeviceInfoModel, AiProcessTime
+    AiStoreMeal, AiService, UidSetModel, Ai_Push_Info, iotdeviceInfoModel, AiProcessTime, Equipment_Info
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
@@ -85,8 +85,6 @@ class AiView(View):
         response = ResponseObject()
         if operation is None:
             return response.json(444, 'error path')
-        elif operation == 'identification':  # ai识别
-            return self.do_ai_identification(request.POST, response)
         elif operation == 'doPayPalCallBack':  # paypal支付回调
             return self.do_pay_by_paypal_callback(request_dict, response)
         elif operation == 'doAlipayCallBack':  # 支付宝支付回调
@@ -109,8 +107,6 @@ class AiView(View):
                 return self.getAiStatus(userID, request_dict, response)
             elif operation == 'commoditylist':  # 获取AI套餐列表
                 return self.do_commodity_list(userID, request_dict, response)
-            elif operation == 'identification':  # ai识别
-                return self.do_ai_identification(request_dict, response)
             elif operation == 'queryInfo':  # 查询消息列表
                 return self.queryInfo(userID, request_dict, response)
             elif operation == 'readInfo':  # 消息已读
@@ -121,8 +117,6 @@ class AiView(View):
                 return self.do_querylist(userID, request_dict, response)
             elif operation == 'getUsingPackage':  # 获取设备当前使用的ai套餐
                 return self.getUsingPackage(request_dict, userID, response)
-            elif operation == 'updateJpushTime':  # 测试ai识别app的推送时间
-                return self.update_jpush_time(userID, request_dict, response)
             else:
                 return response.json(414)
 
@@ -249,7 +243,7 @@ class AiView(View):
                 etkObj = ETkObject(etk='')
                 etk = etkObj.encrypt(uid)
 
-                aiIdentificationUrl = "{DETECT_PUSH_DOMAIN}AiService/identification".format(DETECT_PUSH_DOMAIN=SERVER_DOMAIN_SSL)
+                aiIdentificationUrl = "{DETECT_PUSH_DOMAIN}AiService/identification".format(DETECT_PUSH_DOMAIN=DETECT_PUSH_DOMAINS)
 
                 # mqtt通知设备开启AI识别功能
                 msg = {
@@ -655,267 +649,86 @@ class AiView(View):
         else:
             return HttpResponseRedirect(pay_success_url)
 
-    def do_ai_identification(self, request_dict,response):
-        etk = request_dict.get('etk', None)
-        n_time = request_dict.get('n_time', None)
-        channel = request_dict.get('channel', '1')
-        receiveTime = int(time.time())
+    ## 检查是否有符合条件的标签,并且返回标签坐标位置信息
+    def labelsCoords(self, user_detect_group, rekognition_res, image_size, n_time):
         logger = logging.getLogger('info')
-        logger.info('-----------into----ai--api')
-        logger.info("etk={etk}".format(etk=etk))
-        if not etk:
-            return response.json(444)
-
-        try:
-            # 解密uid及判断长度
-            eto = ETkObject(etk)
-            uid = eto.uid
-            logger.info("uid={uid}".format(uid=uid))
-            if len(uid) != 20 and len(uid) != 14:
-                return response.json(444)
-
-            ##通过uid查出endTime是否过期,并且ai开关是否打开
-            AiServiceQuery = AiService.objects.filter(uid=uid, detect_status=1, use_status=1, endTime__gt=receiveTime).\
-                values('detect_group')
-            if not AiServiceQuery.exists():
-                logger.info('none-----aiService')
-                return response.json(173)
-            detect_group = AiServiceQuery[0]['detect_group']
-            #{}??
-            #
-            file_post_one = request_dict.get('fileOne', None)
-            file_post_two = request_dict.get('fileTwo', None)
-            file_post_three = request_dict.get('fileThree', None)
-
-            file_post_one = file_post_one.replace(' ', '+')
-            file_post_two = file_post_two.replace(' ', '+')
-            file_post_three = file_post_three.replace(' ', '+')
-
-            file_post_one = base64.b64decode(file_post_one)
-            file_post_two = base64.b64decode(file_post_two)
-            file_post_three = base64.b64decode(file_post_three)
-
-            file_list = [file_post_one, file_post_two, file_post_three]
-            del file_post_one, file_post_two, file_post_three
-
-            dir_path = os.path.join(BASE_DIR, 'static/ai/' + uid + '/' + str(receiveTime))
-            if not os.path.exists(dir_path):
-                os.makedirs(dir_path)
-            file_path_list = []
-            i = 1
-            for index in file_list:
-                file_path = dir_path + '/' + str(i) + '.jpg'
-                file_path_list.append(file_path)
-                with open(file_path, 'wb') as f:
-                    f.write(index)
-                    f.close()
-                i += 1
-
-            image_size = 500  # 每张小图片的大小
-            image_colnum = 1  # 合并成一张图后,一行有几个小图
-            MergePic.merge_images(dir_path, image_size, image_colnum)
-            photo = open(dir_path + '.jpg', 'rb')  #打开合成图
-
-            cover = dir_path + '/' + str(i-1) + '.jpg'
-            desc = dir_path + '.jpg'
-            logger.info('----------------cover')
-            logger.info(cover)
-            logger.info(desc)
-            # photo = open(r'E:\test---------------\test\snipaste20220121_215952.jpg', 'rb')
-            #识别合成图片
-            maxLabels = 50
-            minConfidence = 70
-
-            ai_start_time = int(time.time())
-            client = boto3.client(
-                'rekognition',
-                aws_access_key_id='AKIA2E67UIMD6JD6TN3J',
-                aws_secret_access_key='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',
-                region_name='us-east-1')
-            # doc:
-            rekognition_res = client.detect_labels(
-                Image={'Bytes': photo.read()},
-                MaxLabels=maxLabels,
-                MinConfidence=minConfidence)
-            if rekognition_res['ResponseMetadata']['HTTPStatusCode'] != 200:
-                return response.json(173)
-            ai_end_time = int(time.time())
-            labels =rekognition_res['Labels']
-            label_name = []
-            logger.info('--------识别到的标签-------')
-            logger.info(labels)
-            for label in labels:
-                label_name.append(label['Name'])
-                for Parents in label['Parents']:
-                    label_name.append(Parents['Name'])
-            labels = self.checkLabels(detect_group, label_name)    #检查标签是否符合用户选择的识别类型
-            if len(labels['label_list']) == 0:
-                logger.info('没有识别到任何标签-----------------')
-                return response.json(10055)
-            event_type = ','.join(labels['label_type'])
-            label_list = ','.join(labels['label_list'])
-            logger.info(event_type)
-            logger.info(label_list)
-
-            # 上传缩略图到s3
-            upload_cover_path = "{uid}/{channel}/cover{n_time}.jpg".format(uid=uid, channel=channel,
-                                                                           n_time=n_time)  # 封面图
-            upload_desc_path = "{uid}/{channel}/desc{n_time}.jpg".format(uid=uid, channel=channel,
-                                                                         n_time=n_time)  # 详情内容图
-            #多线程上传图片
-            thread_cover = threading.Thread(target=self.upload_s3, args=(cover, upload_cover_path))
-            thread_desc = threading.Thread(target=self.upload_s3, args=(desc, upload_desc_path))
-            thread_cover.start()
-            thread_desc.start()
-            #需要删除图片
-
-
-            #存储消息以及推送
-            is_st = 1  #单图
-            # 查询推送数据
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid). \
-                values('token_val', 'app_type', 'appBundleId', 'm_code', 'push_type', 'userID_id',
-                       'userID__NickName',
-                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval',
-                       'uid_set__detect_group',
-                       'uid_set__channel')
-            if not uid_push_qs.exists():
-                return response.json(173)
-            uid_push_list = []
-            for qs in uid_push_qs:
-                uid_push_list.append(qs)
-
-            nickname = uid_push_list[0]['uid_set__nickname']
-            if not nickname:
-                nickname = uid
-
-            eq_list = []
-            userID_ids = []
-            apns_start_time = 0
-            apns_end_time = 0
-            for up in uid_push_list:
-                push_type = up['push_type']
-                appBundleId = up['appBundleId']
-                token_val = up['token_val']
-                lang = up['lang']
-                tz = up['tz']
-                if tz is None or tz == '':
-                    tz = 0
-
-                # 以下是存库
-                userID_id = up["userID_id"]
-                if userID_id not in userID_ids:
-                    now_time = int(time.time())
-                    eq_list.append(Ai_Push_Info(
-                        userID_id=userID_id,
-                        eventTime=n_time,
-                        eventType=event_type,
-                        devUid=uid,
-                        devNickName=nickname,
-                        Channel=channel,
-                        alarm='检查到{labels} \tChannel:{channel}'.format(labels=','.join(labels['label_list']),
-                                                                       channel=channel),
-                        is_st=is_st,
-                        receiveTime=receiveTime,
-                        addTime=now_time,
-                        storage_location=2
-                    ))
-                    userID_ids.append(userID_id)
-
-                # 推送标题
-                msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
-                # 推送内容
-                msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz, label_list=label_list)
-                kwargs = {
-                    'uid': uid,
-                    'channel': channel,
-                    'event_type': event_type,
-                    'n_time': n_time,
-                    'appBundleId': appBundleId,
-                    'token_val': token_val,
-                    'msg_title': msg_title,
-                    'msg_text': msg_text,
-                }
-                try:
-                    # 推送消息
-                    if push_type == 0:  # ios apns
-                        res = self.do_apns(**kwargs)
-                    elif push_type == 1:  # android gcm
-                        self.do_fcm(**kwargs)
-                    elif push_type == 2:  # android jpush
-                        self.do_jpush(**kwargs)
-                    # if push_type == 1:  # android gcm
-                    #     logger.info('into-------gcm')
-                    #     apns_start_time = int(time.time())
-                    #     res = self.do_fcm(**kwargs)
-                    #     apns_end_time = int(time.time())
-                except Exception as e:
-                    logger.info("errLine={errLine}, errMsg={errMsg}".format(errLine=e.__traceback__.tb_lineno,errMsg=repr(e)))
-                    continue
-
-            Ai_Push_Info.objects.bulk_create(eq_list)
-            return JsonResponse(status=200, data='success', safe=False)
-
-        except Exception as e:
-            print(e)
-            data = {
-                'errLine':e.__traceback__.tb_lineno,
-                'errMsg':repr(e)
-            }
-            return response.json(500, data)
-
-    def delfile(self, path):
-
-        #   read all the files under the folder
-        fileNames = glob.glob(path + r'\*')
-
-        for fileName in fileNames:
-            try:
-                #           delete file
-                os.remove(fileName)
-            except:
-                try:
-                    #               delete empty folders
-                    os.rmdir(fileName)
-                except:
-                    #               Not empty, delete files under folders
-                    delfile(fileName)
-                    #               now, folders are empty, delete it
-                    os.rmdir(fileName)
-
-
-    ## 检查是否有符合条件的标签
-    def checkLabels(self, user_detect_group, labels):
+        labels = rekognition_res['Labels']
+        label_name = []
+        logger.info('--------识别到的标签-------')
+        logger.info(labels)
         labels_type = {
-            '1': ['Person', 'Human'],    #
-            '2': ['Dog', 'Pet', 'Canine', 'Animal'],   #动物
-            '3': ['Car', '', 'Vehicle', 'Transportation', 'Automobile']   #车
+            '1': ['Person', 'Human'],  # 人
+            '2': ['Dog', 'Pet', 'Canine', 'Animal', 'Puppy'],  # 动物
+            '3': ['Car', 'Vehicle', 'Transportation', 'Automobile']  # 车
         }
+        #找出识别的所有标签
+        for label in labels:
+            label_name.append(label['Name'])
+            for Parents in label['Parents']:
+                label_name.append(Parents['Name'])
+
+        #删除用户没有选择的ai识别类型, 并且得出最终识别结果
         user_detect_list = user_detect_group.split(',')
-        user_labels_type = {}
-        for user_detect in user_detect_list:
-            if user_detect in labels_type.keys():
-                user_labels_type[user_detect] = labels_type[user_detect]
-        label_list = []
-        for k, labels_type in user_labels_type.items():
-            for label in labels_type:
-                if label in labels:
-                    label_list.append(label)
-        user_labels_list = list(user_labels_type.keys())
+        user_detect_list = [i.strip() for i in user_detect_list]
+        label_result_list = []
+        new_labels_type = labels_type
+        for key, label_type in labels_type.items():
+            if key in user_detect_list:
+                new_labels_type[key] = label_type
+                for label in label_type:
+                    if label in label_name:
+                        label_result_list.append(label)
+
+        #找出标签边框线位置信息
+        boundingBoxList = []
+        for label in labels:
+            if label['Name'] in label_result_list:
+                for boundingBox in label['Instances']:
+                    boundingBoxList.append(boundingBox['BoundingBox'])
+
+        #找出边框位置信息对应的单图位置并重新计算位置比
+        merge_image_height = image_size['height']
+        merge_image_width = image_size['width']
+        single_height = merge_image_height//image_size['num']
+        new_bounding_box_dict = {}
+        new_bounding_box_dict[n_time+'_0'] = []
+        new_bounding_box_dict[n_time+'_1'] = []
+        new_bounding_box_dict[n_time+'_2'] = []
+        new_bounding_box_dict[n_time+'_3'] = []
+        for k, val in enumerate(boundingBoxList):
+            boundingBoxTop = merge_image_height * val['Top']
+            #找出当前边框属于哪张图片范围
+            boxDict = {}
+            for i in range(image_size['num']):
+                min = i*single_height       #第n张图
+                max = (i+1)*single_height
+                if boundingBoxTop >= min and boundingBoxTop <= max:
+                    # print("属于第{i}张图".format(i=i+1))
+                    boxDict['Width'] = val['Width']
+                    boxDict['Height'] = merge_image_height*val['Height']/single_height
+                    boxDict['Top'] = ((merge_image_height*val['Top'])-(i*single_height))/single_height #减去前i张图片的高度
+                    boxDict['Left'] = val['Left']
+                    boxDict['picName'] = "{n_time}_{i}".format(n_time=n_time,i=i)
+                    # new_bounding_box_list.append(boxDict)
+                    # new_bounding_box_list.append(boxDict)
+                    new_bounding_box_dict["{n_time}_{i}".format(n_time=n_time,i=i)].append(boxDict)
+        # exit(new_bounding_box_list)
+        user_labels_list = list(new_labels_type.keys())
         user_labels_list.sort()
-        return {'label_type': user_labels_list, 'label_list': label_list}
+        return {'label_type': user_labels_list, 'label_list': label_result_list,
+                'new_bounding_box_dict':new_bounding_box_dict}
 
 
     def upload_s3(self, file_path, upload_path):
         try:
-            aws_key = "AKIA2MMWBR4DSFG67DTG" #【你的 aws_access_key】
-            aws_secret = "aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL" # 【你的 aws_secret_key】
+            aws_key = "AKIA2E67UIMD45Y3HL53" #【你的 aws_access_key】
+            aws_secret = "ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw" # 【你的 aws_secret_key】
             session = Session(aws_access_key_id=aws_key,
                               aws_secret_access_key=aws_secret,
-                              region_name="cn-northwest-1")
+                              region_name="us-east-1")
             s3 = session.resource("s3")
             # client = session.client("s3")
-            bucket = "aipush" # 【你 bucket 的名字】 # 首先需要保.证 s3 上已经存在该存储桶,否则报错
+            bucket = "foreignpush" # 【你 bucket 的名字】 # 首先需要保.证 s3 上已经存在该存储桶,否则报错
             upload_data = open(file_path, "rb")
             # upload_key = "test"
             s3.Bucket(bucket).put_object(Key=upload_path, Body=upload_data)
@@ -1095,6 +908,18 @@ class AiView(View):
 
             elif p['is_st'] == 2:
                 pass
+            elif p['is_st'] == 3:
+                # 列表装载回放时间戳标记
+                p['img_list'] = []
+                for i in range(4):
+                    thumbspng = '{uid}/{channel}/{time}_{st}.jpg'.format(uid=devUid, channel=p['Channel'], time=eventTime, st=i)
+                    response_url = aws_s3_client.generate_presigned_url('get_object',
+                                                                             ExpiresIn=300,
+                                                                             Params={
+                                                                                 'Bucket': 'aipush', 'Key': thumbspng
+                                                                             },
+                                                                             )
+                    p['img_list'].append(response_url)
 
             if devUid in uid_type_dict.keys():
                 p['uid_type'] = uid_type_dict[devUid]['type']

+ 7 - 1
Controller/DetectControllerV2.py

@@ -29,6 +29,7 @@ from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel,
     AiService
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
+from django.db.models import Q
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -295,7 +296,12 @@ class DetectControllerViewV2(View):
         if startTime and endTime:
             qs = qs.filter(eventTime__range=(startTime, endTime))
         if eventType:
-            qs = qs.filter(eventType=eventType)
+            if ',' in eventType:   #兼容AI查询
+                eventTypeList = eventType.split(',')
+                eventTypeList = [int(i.strip()) for i in eventTypeList]
+                qs = qs.filter(eventType__in=eventTypeList)
+            else:
+                qs = qs.filter(eventType=eventType)
         uids = request_dict.get('uids', None)
         if uids:
             uid_list = uids.split(',')

+ 1 - 0
Model/models.py

@@ -327,6 +327,7 @@ class Equipment_Info(models.Model):
     userID_id = models.CharField(default='',  db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
     storage_location = models.SmallIntegerField(default=1, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
+    borderCoords = models.TextField(default='', blank=True, verbose_name=u'ai类型图片边框位置信息')
     # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
     # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
     # push_server_status = models.IntegerField(blank=True, default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')

+ 105 - 15
Object/MergePic.py

@@ -1,30 +1,41 @@
 import os
 
 import PIL.Image as Image
+from PIL import ImageDraw
 
 
 def resize_by_width(infile, image_size):
     """按照宽度进行所需比例缩放"""
     im = Image.open(infile)
-    (x, y) = im.size
-    lv = round(x / image_size, 2) + 0.01
-    x_s = int(x // lv)
-    y_s = int(y // lv)
-    print("x_s", x_s, y_s)
-    out = im.resize((x_s, y_s), Image.ANTIALIAS)
-    return out
+    if image_size != 0:
+        (x, y) = im.size
+        lv = round(x / image_size, 2) + 0.01
+        x_s = int(x // lv)
+        y_s = int(y // lv)
+        print("x_s", x_s, y_s)
+        out = im.resize((x_s, y_s), Image.ANTIALIAS)
+        return out
+    else:
+        (x_s, y_s) = im.size
+        print("x_s", x_s, y_s)
+        out = im.resize((x_s, y_s), Image.ANTIALIAS)
+        return out
 
 
 def get_new_img_xy(infile, image_size):
     """返回一个图片的宽、高像素"""
     im = Image.open(infile)
-    (x, y) = im.size
-    lv = round(x / image_size, 2) + 0.01
-    x_s = x // lv
-    y_s = y // lv
-    # print("x_s", x_s, y_s)
-    # out = im.resize((x_s, y_s), Image.ANTIALIAS)
-    return x_s, y_s
+    if image_size != 0:
+        (x, y) = im.size
+        lv = round(x / image_size, 2) + 0.01
+        x_s = x // lv
+        y_s = y // lv
+        # print("x_s", x_s, y_s)
+        # out = im.resize((x_s, y_s), Image.ANTIALIAS)
+        return x_s, y_s
+    else:   #等于0时按照原比例
+        (x_s, y_s) = im.size
+        return x_s, y_s
 
 
 # 定义图像拼接函数
@@ -82,11 +93,90 @@ def merge_images(image_dir_path,image_size,image_colnum):
     x_new = int(x_list[len(x_list) // 5 * 4])
     y_new = int(y_list[len(y_list) // 5 * 4])
     print(" x_new, y_new", x_new, y_new)
-    image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new)  # 调用函数
+    image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new)  # 调用函数.
+    return {'width':x_list[0],'height':sum(y_list),'num':len(y_list)}
     # for img_file in image_fullpath_list:
     #     resize_by_width(img_file,image_size)
 
+def pic_frame(image_path):
+    im = Image.open(image_path)
+    (x, y) = im.size
+
+    width_ratio =  0.5791387557983398
+    height_ratio = 0.23751300573349*(y*4)/y
+    # exit(height_ratio)
+    left_ratio = 0.24959583580493927
+    # exit(y*0.24852335453033447)
+    top_ratio = (y*4*0.504405677318573 - (2*y))/y
+    # exit(top_ratio)
+
+    draw = ImageDraw.Draw(im)
+    # draw.line([(10, 10), (50, 10), (50, 50), (10, 50), (10, 10)], fill=(255, 0, 0), width=5)
+
+    x1 = x*left_ratio
+    y1 = y*top_ratio
+
+    x2 = x1 + (width_ratio*x)
+    y2 = y1
+
+    x3 = x2
+    y3 = y1 + (height_ratio*y)
+
+    x4 = x1
+    y4 = y3
+
+    draw.line([(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1)], fill=(255, 0, 0), width=3)
+    im.show()
+
+
 if __name__ == '__main__':
+    import PIL.Image as Image
+    from PIL import ImageDraw
+    import json
+
+    str = '[{"Width":0.07776174694299698,"Height":0.5436824560165405,"Top":0.36302846670150757,"Left":0.38370513916015625,"picName":"1647415509_0"},{"Width":0.10947742313146591,"Height":0.4826411008834839,"Top":0.4097094237804413,"Left":0.2790755331516266,"picName":"1647415509_0"},{"Width":0.2935298979282379,"Height":0.3697746992111206,"Top":0.621006965637207,"Left":0.6143953204154968,"picName":"1647415509_3"},{"Width":0.35492533445358276,"Height":0.8629811406135559,"Top":0.08606290817260742,"Left":0.3411630690097809,"picName":"1647415509_1"},{"Width":0.39604419469833374,"Height":0.38593751192092896,"Top":0.6001746654510498,"Left":0.060247838497161865,"picName":"1647415509_3"},{"Width":0.1105344295501709,"Height":0.5028191208839417,"Top":0.3258347511291504,"Left":0.0025259912945330143,"picName":"1647415509_3"},{"Width":0.13166509568691254,"Height":0.4821750223636627,"Top":0.34587907791137695,"Left":0.10105808824300766,"picName":"1647415509_3"},{"Width":0.22752150893211365,"Height":0.3825581967830658,"Top":0.5845961570739746,"Left":0.7430258989334106,"picName":"1647415509_3"},{"Width":0.1297324150800705,"Height":0.387117862701416,"Top":0.6101043224334717,"Left":0.4607183039188385,"picName":"1647415509_3"},{"Width":0.2157023847103119,"Height":0.94093257188797,"Top":0.06487464904785156,"Left":0.26413947343826294,"picName":"1647415509_2"},{"Width":0.23323440551757812,"Height":0.8104973435401917,"Top":0.18303179740905762,"Left":0.4748744070529938,"picName":"1647415509_2"},{"Width":0.31273096799850464,"Height":0.9365510940551758,"Top":0.05696296691894531,"Left":0.6696768999099731,"picName":"1647415509_2"},{"Width":0.27037277817726135,"Height":0.8783474564552307,"Top":0.12225198745727539,"Left":0.053227268159389496,"picName":"1647415509_2"},{"Width":0.5476366281509399,"Height":0.4337165951728821,"Top":0.45788294076919556,"Left":0.38325461745262146,"picName":"1647415509_0"}]'
+    str = json.loads(str)
+    for label in str:
+        im = Image.open('D:/devcode/ASJServer_test/static/ai/RBF474J66TLAGHW9111A/1647415509/'+label['picName'] + '.jpg')
+
+        (x, y) = im.size
+
+        width_ratio = label['Width']
+        height_ratio = label['Height']
+        # exit(height_ratio)
+        left_ratio = label['Left']
+        # exit(y*0.24852335453033447)
+        top_ratio = label['Top']
+        # exit(top_ratio)
+
+        draw = ImageDraw.Draw(im)
+        # draw.line([(10, 10), (50, 10), (50, 50), (10, 50), (10, 10)], fill=(255, 0, 0), width=5)
+
+        x1 = x * left_ratio
+        y1 = y * top_ratio
+
+        x2 = x1 + (width_ratio * x)
+        y2 = y1
+
+        x3 = x2
+        y3 = y1 + (height_ratio * y)
+
+        x4 = x1
+        y4 = y3
+
+        draw.line([(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1)], fill=(255, 0, 0), width=3)
+        im.show()
+
+
+
+
+
+
+
+    # image_path = r'D:\devcode\ASJServer_test\static\ai\RBF474J66TLAGHW9111A\1647244844.jpg'  # 图片集地址
+    image_path = r'D:\devcode\ASJServer_test\static\ai\RBF474J66TLAGHW9111A\1647244844\1647244844_0.jpg'  # 图片集地址
+    pic_frame(image_path)
+    exit()
 
     image_dir_path = r'E:\photo\test'  # 图片集地址
     image_size = 500  # 每张小图片的大小