You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mogrify调整图片大小时如何避免损坏(树莓派OCR车牌识别项目)

根因分析
  • 文件读写冲突:你在OCR函数中通过cv2.imread读取try.png后,opencv会持有该文件的句柄,此时你直接调用子进程执行mogrify修改同一路径的文件,写入操作被限制导致文件损坏。
  • 内存操作未落地:你对图像做的resize、绘制轮廓等操作仅在内存中生效,没有通过cv2.imwrite写回磁盘,mogrify操作的原始文件本身就不是你处理后的目标图像。
  • 逻辑矛盾:你提到OCR要求不能提前调整图像尺寸,但OCR函数第一行读完原图就做了全局resize,不符合你预设的业务要求。
  • 可选排查点:如果调整大小后的文件本地打开正常,仅从数据库导出后损坏,需要检查MySQL存储图片的字段类型,BLOB类型最大仅支持64KB,超过大小会截断数据导致图片损坏,需更换为MEDIUMBLOB或LONGBLOB类型。
修复方案

步骤1:修正OCR函数逻辑

保留原始尺寸的原图用于OCR识别,单独复制副本做轮廓检测,避免提前修改原图尺寸,识别完成后直接用opencv做尺寸调整,删除对外部mogrify命令的依赖,避免跨进程文件冲突。
修改后的OCR核心代码如下:

def ocrFunction():
    # 读取原始图像,不修改原图尺寸,适配OCR要求
    original_img = cv2.imread('try.png',cv2.IMREAD_COLOR)
    # 复制副本用于轮廓检测,单独resize该副本
    process_img = original_img.copy()
    process_img = cv2.resize(process_img, (620,480) )

    gray = cv2.cvtColor(process_img, cv2.COLOR_BGR2GRAY) #convert to grey scale
    gray = cv2.bilateralFilter(gray, 11, 17, 17) #Blur to reduce noise
    edged = cv2.Canny(gray, 30, 200) #Perform Edge detection

    # 原有轮廓检测、裁剪、OCR识别逻辑保持不变,全部基于process_img处理
    cnts = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
    screenCnt = None

    # loop over our contours
    for c in cnts:
        # approximate the contour
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.018 * peri, True)
        if len(approx) == 4:
            screenCnt = approx
            break

    if screenCnt is None:
        detected = 0
        print ("No contour detected")
    else:
        detected = 1

    if detected == 1:
        cv2.drawContours(process_img, [screenCnt], -1, (0, 255, 0), 3)

    # Masking the part other than the number plate
    mask = np.zeros(gray.shape,np.uint8)
    new_image = cv2.drawContours(mask,[screenCnt],0,255,-1,)
    new_image = cv2.bitwise_and(process_img,process_img,mask=mask)

    # Now crop
    (x, y) = np.where(mask == 255)
    (topx, topy) = (np.min(x), np.min(y))
    (bottomx, bottomy) = (np.max(x), np.max(y))
    Cropped = gray[topx:bottomx+1, topy:bottomy+1]

    #Read the number plate
    text = pytesseract.image_to_string(Cropped, config='--psm 11')
    print("Detected Number is:",text)
    file = text

    writeConvert(file,'TextC.txt')

    # 识别完成后再调整要上传的图像尺寸,直接用opencv处理,写回磁盘
    upload_img = cv2.resize(original_img, (600,450))
    cv2.imwrite('/home/pi/try.png', upload_img)

    uploadData("/home/pi/try.png","/home/pi/TextC.txt")

步骤2:修改上传函数,删除mogrify调用

删除uploadData函数中调用mogrify的代码行即可,修改后代码如下:

def uploadData(vehicle_plate_image, vehicle_plate_text):
    conn = None
    try:
        conn = mysql.connector.connect(
            host='192.168.1.5',
            user='root',
            password='password',
            charset='utf8',
            port=3306
        )
        if conn.is_connected():
            print('Connected to MySql')

            cur = conn.cursor(buffered=True)
            query = '''INSERT INTO db_gopark.tbl_vehicle (`vehicle_id`, `vehicle_plate_image`,`vehicle_plate_text`) VALUES (NULL,%s,%s);'''
            #image Conversion
            vehicle_plate_image = convertToBinaryData('/home/pi/try.png')
            vehicle_plate_text = convertToBinaryData('/home/pi/TextC.txt')
            # Convert data into tuple format
            image_blob_tuple = (vehicle_plate_image,vehicle_plate_text)
            result = cur.execute(query, image_blob_tuple)
            print('Success Inserting',result)
            conn.commit()
            cur.close()

    except Error as e:
        print(e)

    finally:
        if conn is not None and conn.is_connected():
            conn.close()

可选优化

上传前增加有效性校验,确认调整后的图像无损坏再入库:

# 写回图像后增加校验
test_read = cv2.imread('/home/pi/try.png')
if test_read is None:
    print("图像损坏,终止上传")
    return

内容的提问来源于stack exchange,提问作者The Raspberry Guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:45:02