自动扫描文档图像增强

时间:2018-07-12 13:10:04

标签: python opencv computer-vision image-enhancement

我正在基于Microsoft论文Whiteboard scanning and image enhancement

开发自动图像增强功能

在“白平衡和图像增强”部分中,他们提供了增强的步骤:

首先:他们估计扫描文档或检测到的白板的背景:

  

1。“将白板区域划分为矩形单元格。单元格大小应与我们期望的大致相同   板上单个字符的大小(在我们的实现中为15 x 15像素)。“

然后

  

2。“按照像素的亮度值对每个单元中的像素进行排序。由于墨水吸收了入射光,因此   白板像素要比描边像素高。因此,单元格中的白板颜色是   最高的亮度。实际上,我们将前25个百分位数的像素颜色平均,以减少   传感器噪声引起的误差”

然后

  

3。“通过在RGB空间中局部拟合平面来过滤单元格的颜色。有时存在一些单元格   完全被笔触所覆盖,因此在步骤2中计算出的单元格颜色是不正确的。这些颜色是   被本地拟合平面拒绝为离群值,并由其邻域的插值替换。”

我的问题出在第二步和第三步:

它们如何获取亮度值,我应该将输入图像转换为YUV颜色空间并从Y通道获取亮度值还是直接在RGB颜色空间上工作?

如何在RGB空间中适应局部平面?

这是我的python代码,我试图从输入图像中制作单元格,从YUV颜色空间中获取亮度值,以及一个简单的结果,与从本文中获得的结果相比,这似乎是不正确的。

Python代码:

import cv2
import numpy as np



## Return List of cells from a given Image
def SubImage(image):
    Cells = []
    CellRows = []
    for i in range(0,rows/CellSize):
        subIm = image[i*CellSize:(i+1)*CellSize,:]
        CellRows.append(subIm)
    for img in CellRows:
        for i in range(0,cols/CellSize):
            subIm = img[:,i*CellSize:(i+1)*CellSize]
            Cells.append(subIm)
    return Cells


## Sort luminosity Value
def GetLuminance(Cells):
    luminance = []
    for cel in Cells:
        luminance.append(cel.max())
    return luminance


## Estimate the background color of the white board
def UniformBackground(CelImage,img,luminance):
    a = 0

    for c in range(0,len(CelImage)):
        cel = CelImage[c]
        for i in range(0,cel.shape[0]):
            for j in range(0, cel.shape[1]):
                cel[i,j] = min(1,cel[i,j]/ luminance[c])
    for i in range(0,rows/CellSize):
        for j in range(0,cols/CellSize):
            img[i*CellSize:(i+1)*CellSize,j*CellSize:(j+1)*CellSize] = CelImage[a]
            a = a + 1

if __name__ == '__main__':
    img = cv2.imread('4.png')
    CellSize = 15
    rows,cols,depth = img.shape


    if (rows%CellSize !=0):
        rows = rows - rows%CellSize

    if (cols%CellSize !=0):
        cols = cols - cols%CellSize

    yuvImg = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
    # Get cells from Y channel
    CellsY = SubImage(yuvImg[:,:,0])
    CellsB = SubImage(img[:,:,0])
    CellsG = SubImage(img[:,:,1])
    CellsR = SubImage(img[:,:,2])

    # Get Luminance From Y cells
    LuminanceY = GetLuminance(CellsY)

    # Uniform Background
    UniformBackground(CellsB, img[:,:,0], LuminanceY)
    UniformBackground(CellsG, img[:,:,1], LuminanceY)
    UniformBackground(CellsR,img[:,:,2], LuminanceY)

    #bgrImg = cv2.cvtColor(imgB, cv2.COLOR_GRAY2BGR)
    #print imgB
    cv2.imwrite('unifrom.jpg',img)

输入白板图像:

white Board image

输出图像:

Output image

预期输出:

expected Output

2 个答案:

答案 0 :(得分:0)

temp = cel[i,j]/luminance[c]
if temp > thresh : ##Let thresh be 0.7
   cel[i,j] = 255 

亮度值更高的Cel会转换为白色,而其他Cels则保持不变。The output of the image with uniform background

答案 1 :(得分:0)

让我们逐步解决它:

  
      
  1. “按每个像素的亮度值对它们进行排序”
  2.   

是的,您必须将图像转换为具有亮度分量的其他颜色空间,例如Lab颜色空间。

  

...实际上,我们对前25个百分位数的像素颜色进行平均,以减少传感器噪声引起的误差

意思是,在获得LAB图像后,您需要将其拆分为多个通道,即L通道图像以其直方图表示,例如100 bins(我是在夸大),并且仅取落入的像素最白的垃圾箱(例如从75到100)。现在,在每个单元格中找到白色像素后-例如记住它们!,您可以创建一个遮罩图像,该图像在除被选择为“白色”的像素之外的所有像素上均为0

  

通过在RGB空间中局部拟合平面来过滤单元格的颜色

现在回到RBG空间。如您所见,白板消失了,白板变得越来越暗。 如果您将白板像素RGB颜色绘制为轴为R,G和B的3d世界中的3d点,则会得到近似于平面的散点(因为所有这些白板颜色均为灰色) 。现在,将在上一步中标记为“白板”的点放到平面上。 如何安装飞机?您可以使用this之类的最小二乘法,但是从他们在文章中的书写方式来看,我认为他们已经想到了RANSAC。