我想知道如何使用 OpenCV 在 Python 3 中编写一个函数,该函数接收图像和阈值,并在严重模糊图像并降低质量后返回“暗”或“亮”(越快越好)。这可能听起来很模糊,但任何有效的方法都可以。
你可以试试这个:
import imageio
import numpy as np
f = imageio.imread(filename, as_gray=True)
def img_estim(img, thrshld):
is_light = np.mean(img) > thrshld
return 'light' if is_light else 'dark'
print(img_estim(f, 127))
就我个人而言,我不会为了这样简单的操作而编写任何Python,或者加载OpenCV。如果您绝对必须使用 Python,请忽略此答案并选择其他答案。
您可以在终端的命令行中使用 ImageMagick 来获取图像的平均亮度百分比,其中 100 表示 “全白”,0 表示 “全黑”,如下所示:
convert someImage.jpg -format "%[fx:int(mean*100)]" info:
或者,您可以使用
libvips
,它不太常见,但非常快且非常轻量:
vips avg someImage.png
对于 8 位图像,
vips
答案的范围为 0..255。
请注意,这两种方法都适用于多种图像类型,从 PNG、GIF、JPEG 到 TIFF。
但是,如果你真的想要 Python/OpenCV 代码,我注意到现有的答案都没有做到这一点 - 有些使用不同的库,有些不完整,有些做多余的模糊,有些出于某种未知的原因读取摄像机,并且没有一个可以处理更多多于一张图像或错误。所以,这就是您真正要求的:
#!/usr/bin/env python3
import cv2
import sys
import numpy as np
# Iterate over all arguments supplied
for filename in sys.argv[1:]:
# Load image as greyscale
im = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
if im is None:
print(f'ERROR: Unable to load {filename}')
continue
# Calculate mean brightness as percentage
meanpercent = np.mean(im) * 100 / 255
classification = "dark" if meanpercent < 50 else "light"
print(f'{filename}: {classification} ({meanpercent:.1f}%)')
示例输出
OpenCVBrightOrDark.py g*png nonexistant
g30.png: dark (30.2%)
g80.png: light (80.0%)
ERROR: Unable to load nonexistant
你可以尝试这个,考虑到
image
是灰度图像 -
blur = cv2.blur(image, (5, 5)) # With kernel size depending upon image size
if cv2.mean(blur) > 127: # The range for a pixel's value in grayscale is (0-255), 127 lies midway
return 'light' # (127 - 255) denotes light image
else:
return 'dark' # (0 - 127) denotes dark image
import numpy as np
import cv2
def algo_findDark(image):
blur = cv2.blur(image, (5, 5))
mean = np.mean(blur)
if mean > 85:
return 'light'
else:
return 'dark'
cam = cv2.VideoCapture(0)
while True:
check, frame = cam.read()
frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
ans = algo_findDark(frame_gray)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, ans, (10, 450), font, 3, (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('video', frame)
key = cv2.waitKey(1)
if key == 27:
break
cam.release()
cv2.destroyAllWindows()
你不会说为什么你想这样做。如果您的用例是网站/应用程序的“黑暗模式”,因为您想要反转看起来更好的反转图像而不是变暗的图像,那么这里给出的解决方案都不会完美工作 - 因为它们都会有误报/漏报,就像灰度照片的图像(几乎没有颜色/直方图,但当它们包含人类并且反转时看起来很糟糕,就像照片底片一样)。这些问题无法通过模糊等黑客手段来修复,因为它本质上基于图像的语义,例如它是否包含面部。
如果这是您的用例,那么似乎没有比手动对每个图像进行分类或使用机器学习更好的综合方法了。
对于后一种方法,可以使用 CV 方法轻松处理,例如微调小型神经网络;您可以在 InvertOrNot.com 找到 FLOSS 模型 和 API(使用 PyTorch 和 Onnx 训练 EfficientNet CNN)。