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

Javascript 如何检查文本覆盖图像的百分比?,javascript,python,node.js,opencv,image-processing,Javascript,Python,Node.js,Opencv,Image Processing,有没有办法通过编程计算文本覆盖图像的百分比?我试图在node.js或python中实现这一点,但似乎找不到任何实现这一点的方法-我找到了很多库,它们可以让您分析文本和/或更改图像属性本身(tesseract最初看起来很有希望),但没有任何东西可以返回一个区域或数量-通常只是文本本身。如果您有任何想法,我将不胜感激。很抱歉,我尝试过的代码太少,但在任何地方都找不到任何与此相关的内容。这里有一种使用OpenCV的阈值+轮廓过滤的潜在方法: 将图像转换为灰度和自适应阈值 查找轮廓并使用定义的阈值进行

有没有办法通过编程计算文本覆盖图像的百分比?我试图在node.js或python中实现这一点,但似乎找不到任何实现这一点的方法-我找到了很多库,它们可以让您分析文本和/或更改图像属性本身(tesseract最初看起来很有希望),但没有任何东西可以返回一个区域或数量-通常只是文本本身。如果您有任何想法,我将不胜感激。很抱歉,我尝试过的代码太少,但在任何地方都找不到任何与此相关的内容。

这里有一种使用OpenCV的阈值+轮廓过滤的潜在方法:

  • 将图像转换为灰度和自适应阈值
  • 查找轮廓并使用定义的阈值进行过滤,以删除所有非文本轮廓
  • 在掩码上绘制非文本轮廓,并按位异或仅获取文本
  • 计算文本像素的百分比

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

我们首先使用
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\u阈值
值,该值定义了非文本轮廓的阈值。从本质上说,这个值决定了如果轮廓太大,它必须是一张图片,所以我们希望从图像中过滤这些轮廓。在这种情况下,我们将非文本轮廓定义为大于图像大小
5%
的任何轮廓。这是一个不错的假设,因为单个单词不会超过整个图像区域的
1%
(除非它是一个徽标,但让我们假设为普通文本)

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

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

百分比:13.15%


完整性的完整代码

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()
导入cv2
将numpy作为np导入
image=cv2.imread('1.png')
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
thresh=cv2.自适应阈值(灰色,255,cv2.自适应阈值高斯C,cv2.阈值二进制INV,11,3)
mask=thresh.copy()
mask=cv2.merge([掩码,掩码,掩码])
picture\u threshold=image.shape[0]*image.shape[1]*.05
cnts=cv2.找到的孔(阈值,cv2.外部,cv2.链近似,简单)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
如果区域<图片\u阈值:
cv2.绘制轮廓(掩模,[c],-1,(0,0,0),-1)
遮罩=cv2.CVT颜色(遮罩,cv2.COLOR\u BGR2GRAY)
结果=cv2.按位异或(阈值、掩码)
text_pixels=cv2.countNonZero(结果)
百分比=(文本像素/(image.shape[0]*image.shape[1])*100
打印('百分比:{.2f}%'。格式(百分比))
cv2.imshow('thresh',thresh)
cv2.imshow(“结果”,结果)
cv2.imshow(“面具”,面具)
cv2.waitKey()

这里有一种使用OpenCV的阈值+轮廓过滤的潜在方法:

  • 将图像转换为灰度和自适应阈值
  • 查找轮廓并使用定义的阈值进行过滤,以删除所有非文本轮廓
  • 在掩码上绘制非文本轮廓,并按位异或仅获取文本
  • 计算文本像素的百分比

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

我们首先使用
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\u阈值
值,该值定义了非文本轮廓的阈值。从本质上说,这个值决定了如果轮廓太大,它必须是一张图片,所以我们希望从图像中过滤这些轮廓。在这种情况下,我们将非文本轮廓定义为大于图像大小
5%
的任何轮廓。这是一个不错的假设,因为单个单词不会超过整个图像区域的
1%
(除非它是一个徽标,但让我们假设为普通文本)

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

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

百分比:13.15%


完整性的完整代码

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()
导入cv2
将numpy作为np导入
image=cv2.imread('1.png')
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
thresh=cv2.自适应阈值(灰色,255,cv2.自适应阈值高斯C,cv2.阈值二进制INV,11,3)
mask=thresh.copy()
mask=cv2.merge([掩码,掩码,掩码])
picture\u threshold=image.shape[0]*image.shape[1]*.05
cnts=cv2.找到的孔(阈值,cv2.外部,cv2.链近似,简单)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
如果区域<图片\u阈值:
cv2.绘制轮廓(掩模,[c],-1,(0,0,0),-1)
遮罩=cv2.CVT颜色(遮罩,cv2.COLOR\u BGR2GRAY)
结果=cv2.按位异或(阈值、掩码)
text_pixels=cv2.countNonZero(结果)
百分比=(文本像素/(image.shape[0]*image.shape[1])*100
打印('百分比:{.2f}%'。格式(百分比))
cv2.imshow('thresh',thresh)
cv2.imshow(“结果”,结果)
cv2.imshow(“面具”,
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()