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

如何用TensorFlow与Python提取电表图像中的黑色数字区域?

用TensorFlow提取电表黑色数字区域的解决方案

我懂你碰到的这个棘手问题——之前用OpenCV固定阈值加findContours搞不定电表的黑色数字区域,毕竟光照不均、局部阴影这些情况一出现,固定阈值就彻底失效了。而电表刚好是白背景黑数字的明确场景,用TensorFlow来处理会更灵活精准,给你几个实用的方案:

方法一:自定义二分类CNN模型(适配你的专属场景)

如果能收集到一批电表照片,这个方法的效果会最贴合你的需求,毕竟是专门针对你的场景训练的模型:

  • 准备数据集:
    收集几十张不同光照、角度的电表照片,用标注工具(比如LabelMe)手动框选数字区域,生成对应的掩码图——数字区域标为1,背景标为0。把图像统一缩放到固定尺寸(比如256×256)。
  • 构建简单的分割模型:
    这个模型用CNN做下采样提取特征,再通过转置卷积恢复尺寸,最终输出二值掩码:
    import tensorflow as tf
    from tensorflow.keras import layers
    
    def build_digit_segmenter(input_shape=(256, 256, 3)):
        inputs = tf.keras.Input(shape=input_shape)
        # 下采样提取特征
        x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
        x = layers.MaxPooling2D((2, 2))(x)
        x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)
        x = layers.MaxPooling2D((2, 2))(x)
        # 上采样恢复图像尺寸
        x = layers.Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same', activation='relu')(x)
        x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), padding='same', activation='relu')(x)
        # 输出二分类掩码(sigmoid激活输出0-1之间的概率)
        outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(x)
        
        model = tf.keras.Model(inputs=inputs, outputs=outputs)
        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
        return model
    
    # 初始化模型
    model = build_digit_segmenter()
    
  • 训练模型:
    把标注好的图像和掩码分成训练集和验证集,开始训练:
    # 假设train_images(归一化到0-1)和train_masks是你的训练数据,形状分别为(None,256,256,3)和(None,256,256,1)
    model.fit(train_images, train_masks, epochs=20, batch_size=8, validation_split=0.2)
    
  • 提取数字区域:
    用训练好的模型预测新图像,转成二值掩码后和原图像做位运算,就能分离出数字区域:
    import cv2
    import numpy as np
    
    def extract_digits(image):
        # 调整图像尺寸到模型输入大小并归一化
        resized_img = tf.image.resize(image, (256, 256)) / 255.0
        resized_img = tf.expand_dims(resized_img, 0)
        # 预测掩码
        pred_mask = model.predict(resized_img)[0]
        # 转成二值图(阈值设为0.5,概率大于0.5的判定为数字区域)
        binary_mask = (pred_mask > 0.5).astype(np.uint8) * 255
        # 恢复原图像尺寸
        binary_mask = tf.image.resize(binary_mask, (image.shape[0], image.shape[1])).numpy().astype(np.uint8)
        # 用掩码提取数字区域
        digit_area = cv2.bitwise_and(image, image, mask=binary_mask.squeeze())
        return digit_area
    

方法二:用预训练语义分割模型快速上手

如果没精力标注数据集,可以用TensorFlow Hub里的预训练分割模型(比如DeepLabV3+),这类模型已经学习过大量图像的特征,能快速应对复杂场景:

import tensorflow as tf
import tensorflow_hub as hub
import cv2

# 加载预训练语义分割模型
segmenter = hub.load("https://tfhub.dev/tensorflow/deeplabv3+/1")

def get_digit_area_with_pretrained(image):
    # 模型输入要求:RGB图像,尺寸任意,归一化到0-1
    input_tensor = tf.convert_to_tensor(image, dtype=tf.float32) / 255.0
    input_tensor = input_tensor[tf.newaxis, ...]
    # 预测分割结果
    result = segmenter(input_tensor)
    segmentation_mask = result['segmentation_mask'][0]
    # 因为电表数字是深色,我们可以筛选出像素值较低的区域(对应模型中的"dark object"类别)
    # 或者根据实际结果调整阈值,把数字区域单独提取出来
    binary_mask = (segmentation_mask == 0).astype(np.uint8) * 255 # 这里类别编号需要根据实际测试调整
    digit_area = cv2.bitwise_and(image, image, mask=binary_mask)
    return digit_area

注意: 预训练模型的类别编号需要你实际测试后调整,比如有些模型会把深色物体归为特定类别,你可以打印segmentation_mask的取值范围来找到对应数字的类别。

方法三:TensorFlow自适应阈值(无训练快速验证)

如果不想碰模型,也可以用TensorFlow实现自适应阈值,比OpenCV的固定阈值更能应对光照变化:

import tensorflow as tf
import cv2

def adaptive_threshold_tf(image):
    # 转灰度图
    gray = tf.image.rgb_to_grayscale(image)
    # 计算15×15窗口内的局部均值(窗口大小可以根据电表数字大小调整)
    kernel = tf.ones((15, 15), tf.float32) / (15*15)
    local_mean = tf.nn.conv2d(gray, kernel[..., tf.newaxis, tf.newaxis], strides=1, padding='SAME')
    # 自适应阈值:像素值比局部均值低5以上的判定为数字区域(黑色)
    thresholded = tf.where(gray < local_mean - 5, 255, 0)
    # 转成OpenCV能用的格式
    binary_mask = thresholded.numpy().squeeze().astype(np.uint8)
    # 提取数字区域
    digit_area = cv2.bitwise_and(image, image, mask=binary_mask)
    return digit_area

这个方法不需要训练,直接跑就能出结果,适合快速验证效果,窗口大小和阈值差可以根据你的电表照片调整。


内容的提问来源于stack exchange,提问作者Ignacio Mtz De Salinas Ureta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:51:22