标签: image-thresholding

使用OpenCV自动调整一张纸的彩色照片的对比度和亮度

拍摄一张纸时(例如,使用电话摄像头),我得到以下结果(左图)(jpg 在此处下载)。所需的结果(使用图像编辑软件手动处理)在右侧:

我想用openCV处理原始图像,以自动获得更好的亮度/对比度(以使背景更白)

假设:图像具有A4纵向格式(在本主题中,我们无需对其进行透视变形),并且纸页为白色,可能带有黑色或彩色的文本/图像。

到目前为止,我已经尝试过:

  1. 各种自适应阈值方法,例如高斯,OTSU(请参阅OpenCV doc 图像阈值)。通常可以与OTSU配合使用:

    ret, gray = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
    
    Run Code Online (Sandbox Code Playgroud)

    但仅适用于灰度图像,不适用于彩色图像。此外,输出是二进制(白色或黑色),我不希望这样:我更喜欢保留彩色非二进制图像作为输出

  2. 直方图均衡

    • 应用于Y(在RGB => YUV变换之后)
    • 或应用于V(在RGB => HSV变换之后),

    如本建议答案直方图均衡化不是彩色图像的工作- OpenCV的)或该一个OpenCV的Python的equalizeHist彩色图像):

    img3 = cv2.imread(f)
    img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2YUV)
    img_transf[:,:,0] = cv2.equalizeHist(img_transf[:,:,0])
    img4 = cv2.cvtColor(img_transf, cv2.COLOR_YUV2BGR)
    cv2.imwrite('test.jpg', img4)
    
    Run Code Online (Sandbox Code Playgroud)

    或使用HSV:

    img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2HSV)
    img_transf[:,:,2] = cv2.equalizeHist(img_transf[:,:,2])
    img4 = cv2.cvtColor(img_transf, cv2.COLOR_HSV2BGR)
    
    Run Code Online (Sandbox Code Playgroud)

    不幸的是,结果非常糟糕,因为它会在本地创建可怕的微对比度(?):

    我还尝试了YCbCr,这很相似。

  3. 我还尝试了CLAHE(对比度受限的自适应直方图均衡化),范围tileGridSize从 …

python opencv image-processing computer-vision image-thresholding

40
推荐指数
5
解决办法
3094
查看次数

python中的二值图像去噪

对于我的项目,我正在尝试使用 python 中的 openCV 对图像进行二值化。我使用 openCV 的自适应高斯阈值来转换图像,结果如下: 在此输入图像描述

我想使用二进制图像进行 OCR,但它的噪音太大。有什么方法可以去除Python中的二值图像中的噪声吗?我已经尝试过 openCV 的 fastNlMeansDenoising 但它没有什么区别。

PS 也欢迎更好的二值化选项

python opencv image-processing image-thresholding

5
推荐指数
1
解决办法
1万
查看次数

适当的图像阈值处理以使用 opencv 在 python 中为 OCR 做准备

我真的是 opencv 的新手,也是 python 的初学者。

我有这张图片:

原始 bmp 24 位图像

我想以某种方式应用适当的阈值来保留 6 位数字。

更大的图景是我打算尝试分别对每个数字的图像执行手动 OCR,在每个数字级别上使用 k-最近邻算法 (kNearest.findNearest)

问题是我无法充分清理数字,尤其是带有蓝色水印的“7”数字。

到目前为止,我尝试过的步骤如下:

我正在从磁盘读取图像

# IMREAD_UNCHANGED is -1
image = cv2.imread(sys.argv[1], cv2.IMREAD_UNCHANGED)
Run Code Online (Sandbox Code Playgroud)

然后我只保留蓝色通道以去除数字“7”周围的蓝色水印,有效地将其转换为单通道图像

image = image[:,:,0] 
# openned with -1 which means as is, 
# so the blue channel is the first in BGR
Run Code Online (Sandbox Code Playgroud)

单通道 - 仅红色 - 图像

然后我将它乘以一点以增加数字和背景之间的对比度:

image = cv2.multiply(image, 1.5)
Run Code Online (Sandbox Code Playgroud)

相乘图像以增加对比度

最后我执行 Binary+Otsu 阈值处理:

_,thressed1 = cv2.threshold(image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
Run Code Online (Sandbox Code Playgroud)

二值欧胡岛阈值图像

正如您所看到的,最终结果非常好,除了数字“7”保留了很多噪音。

如何改善最终结果?请在可能的情况下提供图像示例结果,这比仅代码片段更好理解。

python ocr opencv image-processing image-thresholding

4
推荐指数
1
解决办法
2483
查看次数

opencv 阈值 THRESH_BINARY 对彩色图像有什么作用?

文档THRESH_BINARY说:

dst(x,y) = maxval if src(x,y) > thresh else 0

这对我来说并不意味着这不适用于彩色图像。即使应用于彩色图像,我也期望有两种颜色的输出,但输出是多色的。为什么?当像素x,y被分配的可能值是maxval0仅?

例子:

from sys import argv
import cv2
import numpy as np

img = cv2.imread(argv[1])

ret, threshold = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY)

cv2.imshow('threshold', threshold)
cv2.imshow('ori', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

python opencv image-processing image-thresholding

3
推荐指数
2
解决办法
1709
查看次数

如何在不使用 OpenCV Python 中的 split 函数的情况下获取图像的单色通道?

我想突出显示实时手势识别的手。我观察到使用 cv2.imsplit 函数,对于不同的颜色通道,手的图像会以不同的方式突出显示。但是这个拆分函数在时间上是非常昂贵的。我无法使用 Numpy 索引执行相同的功能(如官方页面所示

python opencv numpy gesture-recognition image-thresholding

3
推荐指数
1
解决办法
7043
查看次数

如何检测与背景融合的物体?

我是初学者,我正在尝试将轮廓应用到左侧的白色遥控器上,该遥控器与背景颜色相同。 在此输入图像描述

a = cv2.imread(file_name)
imgGray = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)

imgGray = cv2.GaussianBlur(imgGray,(11,11),20)

k5 = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]])
imgGray = cv2.filter2D(imgGray,-1,k5)

cv2.namedWindow("Control")
cv2.createTrackbar("blocksize","Control",33,1000,f)
cv2.createTrackbar("c","Control",3,100,f)
while True:
    strel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
    blocksize = cv2.getTrackbarPos("blocksize","Control")
    c = cv2.getTrackbarPos("c","Control")

    if blocksize%2==0:
        blocksize += 1
    thrash = cv2.adaptiveThreshold(imgGray,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV,blockSize=blocksize,C=c)
    thrash1 = cv2.adaptiveThreshold(imgGray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,blockSize=blocksize,C=c)

    cv2.imshow("mean",thrash)
    cv2.imshow("gaussian",thrash1)
    #r,thrash = cv2.threshold(imgGray,150,255,cv2.THRESH_BINARY_INV)
    key = cv2.waitKey(1000)
    if key == 32 or iter == -1:
         break


edges = cv2.Canny(thrash,100,200)
cv2.imshow('sharpen',sharpen)
cv2.imshow('edges',edges)
cv2.imshow('grey ',imgGray)
cv2.imshow('thrash ',thrash)
cv2.waitKey(0)
circles = cv2.HoughCircles(imgGray,cv2.HOUGH_GRADIENT,1,60,param1=240,param2=50,minRadius=0,maxRadius=0)
contours,_ = cv2.findContours(thrash,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
putlabel(circles,a,contours)
Run Code Online (Sandbox Code Playgroud)

这些是我尝试过的,我也尝试过形态学操作,如膨胀、腐蚀、开闭,但我仍然无法获得结果。

下面是我的最佳结果,但噪音太严重,而且遥控器的轮廓也没有完全清晰。 在此输入图像描述

python opencv image-processing computer-vision image-thresholding

3
推荐指数
1
解决办法
3716
查看次数

我可以在 OpenCV 中为 Otsu 阈值添加偏差吗?

这是我的例子。左到右:

  1. 原图
  2. 灰度 + (3,3) 高斯模糊
  3. 大津阈值+反转像素

在此处输入图片说明

我想捕捉更多笔触的微弱部分。我知道 Otsu Thresholding 试图在像素强度直方图的两个峰值之间应用阈值点,但我想稍微偏置一下,以便我可以捕获一些较亮的像素。

可以开箱即用吗?还是我需要做一些手动?

python opencv image-thresholding

2
推荐指数
1
解决办法
664
查看次数

在 OpenCV 中检测(并拒绝)从计算机/电视屏幕拍摄的扭曲图像

我的一些算法依赖于根据检测到的重要水平线的计数来分割图像,从计算机屏幕或监视器拍摄的图像可能会出现问题,因为失真会导致二值化不良和定义不明确的区域。

监视器的摄像头捕获: 捕获监视器

理想的情况是相机捕获的图像在渲染时不会出现通过监视器捕获而导致的失真(因为它以数字方式显示),但是是否可以使用 opencv 检测到图像是以这种方式捕获的,因此如果出现以下情况则拒绝它是这样吗(因为无法处理)?

python opencv image-processing image-thresholding

2
推荐指数
1
解决办法
1265
查看次数

我想使用 python 对图像中的像素应用阈值。我哪里做错了?

我想生成作为阈值的输出。还有我的错误:

img_thres = n_pix[y, x]
TypeError: 'int' 对象不可下标

import cv2
import numpy as np
import matplotlib as plt

img = cv2.imread("cicek.png",0)
img_rgb = cv2.imread("cicek.png")

h = img.shape[0]
w = img.shape[1]

img_thres= []
n_pix = 0
# loop over the image, pixel by pixel
for y in range(0, h):
    for x in range(0, w):
        # threshold the pixel
        pixel = img[y, x]
        if pixel < 0.5:
            n_pix = 0
        img_thres = n_pix[y, x]

cv2.imshow("cicek", img_thres)
Run Code Online (Sandbox Code Playgroud)

python image image-processing threshold image-thresholding

1
推荐指数
1
解决办法
8227
查看次数