为了账号安全,请及时绑定邮箱和手机立即绑定

如何检查文本覆盖的图像的百分比?

如何检查文本覆盖的图像的百分比?

jeck猫 2022-01-01 20:37:54
有没有办法以编程方式计算文本覆盖图像的百分比?我正在尝试在 node.js 或 python 中执行此操作,但似乎无法找到任何可以执行此操作的内容-我发现了很多可让您分析文本和/或更改图像属性本身的库(tesseract最初看起来很有希望),但没有什么可以给我回一个区域或数量——通常只是文本本身。任何想法将不胜感激,抱歉缺少我尝试过的代码,但在任何地方都找不到任何关于此的信息。
查看完整描述

1 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

这是在 OpenCV 中使用阈值 + 轮廓过滤的潜在方法:

  • 将图像转换为灰度和自适应阈值

  • 使用定义的阈值查找轮廓并过滤以删除所有非文本轮廓

  • 将非文本轮廓绘制到掩码上并按位异或以仅获取文本

  • 计算文本像素的百分比


由于您没有提供输入图像,我将使用教科书中的示例图像。注意一些文本是彩色的,并且有一张图片来模拟带有文本的普通图像。

//img1.sycdn.imooc.com//61d04b380001c06504560975.jpg

我们首先将图像转换为灰度和自适应阈值cv2.adaptiveThreshold()以获得二值图像。


image = cv2.imread('1.png')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,3)

接下来,我们使用 找到轮廓cv2.findContours()并使用轮廓区域进行过滤cv2.contourArea()。我们定义一个picture_threshold值来定义非文本轮廓的阈值。从本质上讲,这个值决定了如果轮廓太大,它一定是一张图片,所以我们要从我们的图像中过滤掉这些轮廓。在这种情况下,我们将非文本轮廓定义为任何大于5%图像大小的轮廓。这是一个不错的假设,因为单个单词不会大于1%整个图像区域的大小(除非它是徽标,但我们假设只是普通文本)。


阈值二值图像(左)和蒙版上过滤的非文本轮廓(右)

//img1.sycdn.imooc.com//61d04b440001e8fc04330961.jpg

mask = thresh.copy()

mask = cv2.merge([mask,mask,mask])


picture_threshold = image.shape[0] * image.shape[1] * .05

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:

    area = cv2.contourArea(c)

    if area < picture_threshold:

        cv2.drawContours(mask, [c], -1, (0,0,0), -1)

为了去除不需要的轮廓,我们执行按位异或操作来获得只有文本的过滤图像。这是我们将计算文本像素百分比的图像。

//img1.sycdn.imooc.com//61d04b4f0001856004520979.jpg

mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)

result = cv2.bitwise_xor(thresh, mask)

由于我们仅隔离了图像上的文本轮廓,因此我们只需使用 计算图像上的白色像素数cv2.countNonZero()。我们可以通过除以图像的面积来获得文本像素的百分比。结果如下:


百分比:13.15%


text_pixels = cv2.countNonZero(result)

percentage = (text_pixels / (image.shape[0] * image.shape[1])) * 100

print('Percentage: {:.2f}%'.format(percentage))

完整代码


import cv2

import numpy as np


image = cv2.imread('1.png')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,3)


mask = thresh.copy()

mask = cv2.merge([mask,mask,mask])


picture_threshold = image.shape[0] * image.shape[1] * .05

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:

    area = cv2.contourArea(c)

    if area < picture_threshold:

        cv2.drawContours(mask, [c], -1, (0,0,0), -1)


mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)

result = cv2.bitwise_xor(thresh, mask)


text_pixels = cv2.countNonZero(result)

percentage = (text_pixels / (image.shape[0] * image.shape[1])) * 100

print('Percentage: {:.2f}%'.format(percentage))


cv2.imshow('thresh', thresh)

cv2.imshow('result', result)

cv2.imshow('mask', mask)

cv2.waitKey()


查看完整回答
反对 回复 2022-01-01
  • 1 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号