如何使用 OpenCV 生成纸质背景
Posted
技术标签:
【中文标题】如何使用 OpenCV 生成纸质背景【英文标题】:How to generate a paper-like background with OpenCV 【发布时间】:2019-01-09 18:52:31 【问题描述】:我正在尝试使用 OpenCV 实现一个随机的纸状背景。 附件示例显示了真实的纸质文档工件(请忽略上面的笔迹)。
简单的原纸效果,只要加上噪点就可以轻松实现
import cv2
import numpy as np
BG_COLOR = 209
def blank_image(width=1024, height=1024):
img = np.full((height, width, 1), BG_COLOR, np.uint8)
return img
def noisy(image):
row, col, ch = image.shape
mean = 0
sigma = 10
gauss = np.random.normal(mean, sigma, (row, col, ch))
gauss = gauss.reshape(row, col, ch)
noisy = gauss + image
return noisy
if __name__ == '__main__':
img = blank_image()
cv2.imwrite('out.jpg', noisy(img))
但是如果没有上面的伪影,它看起来太统一了:
我想知道从第一张图片生成这种随机结构的最佳方法是什么。
【问题讨论】:
人们想知道的地方,实验一定会发生。创建一些随机坐标,涂抹一些涂抹,也许可以创建一些非常轻的“污垢”“邮票”并应用它们。将 2 个坐标与一条较暗(或较浅)的细线连接以形成折痕。在靠近边缘的地方涂抹污迹(脏手会翻页的地方)。发挥创意。不过,这一切都不值得就 SO 提出问题——因此投票结束“必然会引发讨论”。如果您的实验代码失败了,请回来。这可能会更适合某种“艺术”论坛 还有一个提示,如果你有 gimp2 - 它有脚本过滤器,我猜它会创建“纸状”纹理。检查它的层(或窃取部分)并将它们作为半透明 png 应用到您的图片 - 也可以使用马克杯污渍;o) 最简单的解决方案是拍摄空白页面的照片,并使用这些照片生成背景。要么为每种情况随机选择一张图片,要么分离出这些伪影并将它们粘贴到随机位置。 看看程序噪声纹理和相关主题。 lodev.org/cgtutor/randomnoise.html 是我得到的第一个谷歌搜索结果。 【参考方案1】:受 BoboDarph 提供的解决方案的启发,我创建了一个类似纸的纹理。现在我需要从上面的真实照片中添加工件。 代码如下:
import cv2
import numpy as np
BG_COLOR = 209
BG_SIGMA = 5
MONOCHROME = 1
def blank_image(width=1024, height=1024, background=BG_COLOR):
"""
It creates a blank image of the given background color
"""
img = np.full((height, width, MONOCHROME), background, np.uint8)
return img
def add_noise(img, sigma=BG_SIGMA):
"""
Adds noise to the existing image
"""
width, height, ch = img.shape
n = noise(width, height, sigma=sigma)
img = img + n
return img.clip(0, 255)
def noise(width, height, ratio=1, sigma=BG_SIGMA):
"""
The function generates an image, filled with gaussian nose. If ratio parameter is specified,
noise will be generated for a lesser image and then it will be upscaled to the original size.
In that case noise will generate larger square patterns. To avoid multiple lines, the upscale
uses interpolation.
:param ratio: the size of generated noise "pixels"
:param sigma: defines bounds of noise fluctuations
"""
mean = 0
assert width % ratio == 0, "Can't scale image with of size and ratio ".format(width, ratio)
assert height % ratio == 0, "Can't scale image with of size and ratio ".format(height, ratio)
h = int(height / ratio)
w = int(width / ratio)
result = np.random.normal(mean, sigma, (w, h, MONOCHROME))
if ratio > 1:
result = cv2.resize(result, dsize=(width, height), interpolation=cv2.INTER_LINEAR)
return result.reshape((width, height, MONOCHROME))
def texture(image, sigma=BG_SIGMA, turbulence=2):
"""
Consequently applies noise patterns to the original image from big to small.
sigma: defines bounds of noise fluctuations
turbulence: defines how quickly big patterns will be replaced with the small ones. The lower
value - the more iterations will be performed during texture generation.
"""
result = image.astype(float)
cols, rows, ch = image.shape
ratio = cols
while not ratio == 1:
result += noise(cols, rows, ratio, sigma=sigma)
ratio = (ratio // turbulence) or 1
cut = np.clip(result, 0, 255)
return cut.astype(np.uint8)
if __name__ == '__main__':
cv2.imwrite('texture.jpg', texture(blank_image(background=230), sigma=4, turbulence=4))
cv2.imwrite('texture-and-noise.jpg', add_noise(texture(blank_image(background=230), sigma=4), sigma=10))
cv2.imwrite('noise.jpg', add_noise(blank_image(1024, 1024), sigma=10))
生成的图片:
【讨论】:
你添加了工件吗? @JeruLuke,目前还没有我想如何添加图像边缘+黑色背景以上是关于如何使用 OpenCV 生成纸质背景的主要内容,如果未能解决你的问题,请参考以下文章
如何根据相机校准(C++)生成的真实数据使用opencv模拟失真?
如何使openCV背景减法KNN算法持续更长时间,跟踪一个没有移动的前景对象