Python批量将图片中的字体切出单个图片

作者 :
免费
  • 正文
  • 图片似乎有很多小的元素,如标点符号。为了解决这个问题,通过筛选轮廓的面积来忽略小的元素。我们可以设定一个最小面积阈值,例如min_area,然后仅考虑那些面积大于这个阈值的连通组件(轮廓)。这样,较小的标点符号或其他不希望裁剪的元素就不会被考虑。下面是考虑到最小面积阈值的代码:这里,我添加了一个min_area参数,设置为300。这意味着小于300像素的连通区域(可能是标点符号或噪声)将不会被考虑。您可以根据需要调整这个值。

    好,图片切出来1:1

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img, min_area=1):
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    kernel=np.ones((3,3),np.uint8)
    binary=cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    ifcv2.contourArea(contour) <min_area:
    continue
    x, y, w, h=cv2.boundingRect(contour)
    max_side=max(w, h)
    canvas=np.zeros((max_side, max_side, 4), dtype=np.uint8)
    x_offset= (max_side-w) //2
    y_offset= (max_side-h) //2
    canvas[y_offset:y_offset+h, x_offset:x_offset+w] =img[y:y+h, x:x+w]
    slices.append(canvas)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

    可以看到了“网”字的问题:字的一部分与其他部分有一些小的间隔或中断,这使得它们被识别为两个独立的连通组件。因此,当进行切片时,它们被视为两个独立的区域并分别被切割。为了处理这种情况,使用形态学的“闭运算”来连接这些小的间隔或中断。闭运算是先进行膨胀操作然后再进行腐蚀操作,可以有效地“关闭”小的空隙。增加了闭运算,增加了对二值化结果的形态学闭运算处理,能有效地处理“网”字或其他具有小间隔的字符。

    好,图片比例为1:1,网字也能切出来。

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img):
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    kernel=np.ones((3,3),np.uint8)
    binary=cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    x, y, w, h=cv2.boundingRect(contour)
    max_side=max(w, h)
    canvas=np.zeros((max_side, max_side, 4), dtype=np.uint8)
    x_offset= (max_side-w) //2
    y_offset= (max_side-h) //2
    canvas[y_offset:y_offset+h, x_offset:x_offset+w] =img[y:y+h, x:x+w]
    slices.append(canvas)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

    测试用例

    Python批量将图片中的字体切出单个图片-完美源码

    Python批量将图片中的字体切出单个图片-完美源码

    Python批量将图片中的字体切出单个图片-完美源码

     

    网字可以切出来,字体能切,但图片比例为原始图片大小,字体是单独的,其它部分为透明。

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img):
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    kernel=np.ones((3,3),np.uint8)
    binary=cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    x, y, w, h=cv2.boundingRect(contour)
    # 创建一个全透明的图片,与原图大小一致
    char_img=np.zeros_like(img)
    # 将裁剪的字符放入新图片的对应位置
    char_img[y:y+h, x:x+w] =img[y:y+h, x:x+w]
    slices.append(char_img)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

     

    网字切出来了,但宽高比不同。但宽高比相差不多。

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img):
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    # 使用闭运算连接小的间隔
    kernel=np.ones((3,3),np.uint8)
    binary=cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    x, y, w, h=cv2.boundingRect(contour)
    # 增加一个小的边距
    margin=5
    x=max(0, x-margin)
    y=max(0, y-margin)
    w=min(w+2*margin, img.shape[1] -x)
    h=min(h+2*margin, img.shape[0] -y)
    char_img=img[y:y+h, x:x+w]
    slices.append(char_img)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

    网字切成了两张图

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img):
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    x, y, w, h=cv2.boundingRect(contour)
    # 增加一个小的边距
    margin=5
    x=max(0, x-margin)
    y=max(0, y-margin)
    w=min(w+2*margin, img.shape[1] -x)
    h=min(h+2*margin, img.shape[0] -y)
    char_img=img[y:y+h, x:x+w]
    slices.append(char_img)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

    本代码对于“网”切的不是很好,但学习可以

    import cv2
    import numpy as np
    import os
    def slice_characters_from_image(img):
    # 获取图像的alpha通道作为二值化的依据
    alpha_channel=img[:, :, 3]
    _, binary=cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY)
    # 查找连通组件
    contours, _=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    slices= []
    forcontourincontours:
    x, y, w, h=cv2.boundingRect(contour)
    # 根据边界切片
    char_img=img[y:y+h, x:x+w]
    # 创建一个正方形透明画布
    max_side=max(w, h)
    canvas=np.zeros((max_side, max_side, 4), dtype=np.uint8)
    x_offset= (max_side-w) //2
    y_offset= (max_side-h) //2
    canvas[y_offset:y_offset+h, x_offset:x_offset+w] =char_img
    slices.append(canvas)
    returnslices
    input_folder = '切片'
    output_folder = 'output_slices'
    if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    for img_name in os.listdir(input_folder):
    ifimg_name.lower().endswith(('.png', '.jpg', '.jpeg')):
    img_path=os.path.join(input_folder, img_name)
    img=cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    slices=slice_characters_from_image(img)
    fori, slice_imginenumerate(slices):
    output_name=os.path.join(output_folder, f'slice_{os.path.splitext(img_name)[0]}_{i}.png')
    cv2.imwrite(output_name, slice_img)
    print("批量处理完成!")

    END
    如本资源侵犯了您的权益,请联系投诉邮箱admin@wmphp.com进行举报!我们将在收到邮件的1个小时内处理完毕。 本站仅为平台,发布的资源均为用户投稿或转载!所有资源仅供参考学习使用,请在下载后的24小时内删除,禁止商用! Wmphp.com(完美源码)助力正版,如您有自己的原创产品,可以联系客服投稿,代理出售! Wmphp.com(完美源码)客服QQ:136882447 Wmphp.com(完美源码)商务电话(仅对企业客户/个人用户):15120086569 (微信同步) 请注意:本站不提供任何免费的技术咨询服务,为了节约时间,下载前 请确认自己会技术
    完美源码 » Python批量将图片中的字体切出单个图片
    3529+

    本站勉强运行

    3803+

    用户总数

    692+

    资源总数

    0+

    今日更新

    2024-5-13

    最后更新时间