Автоматическое улучшение изображения отсканированного документа
Я разрабатываю автоматическое улучшение изображений на основе сканирования бумаги Microsoft Paperboard и улучшения изображений
в разделе "Балансировка белого и улучшение изображения" представлены шаги для улучшения:
Во-первых: они оценивают фон отсканированного документа или обнаруженной белой доски:
1. "Разделите область доски на прямоугольные ячейки. Размер ячейки должен быть примерно таким же, как мы ожидаем, размер одного символа на доске (15 на 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)
Введите изображение с белой доски:
Выходное изображение:
Ожидаемый результат:
2 ответа
temp = cel[i,j]/luminance[c]
if temp > thresh : ##Let thresh be 0.7
cel[i,j] = 255
Cel с большим значением яркости преобразуется в белый, остальные cel остались без изменений. Вывод изображения с равномерным фоном
Давайте разберемся с этим шаг за шагом:
- "Сортировать пиксели в каждой ячейке по их значениям яркости"
Да, вы должны преобразовать изображение в другое цветовое пространство, которое имеет компонент яркости, например, цветовое пространство Lab.
... На практике мы усредняем цвета пикселей в верхних 25 процентилях, чтобы уменьшить ошибку, вносимую шумом датчика
Это означает, что после того, как вы получите, скажем, изображение LAB, вам нужно разделить его на каналы, чтобы изображение канала L, взяло его гистограмму, скажем, со 100 ячейками (я преувеличиваю) и взяло только пиксели, попадающие в самые белые ячейки. (скажем, от 75 до 100). Теперь, когда вы нашли белые пиксели в каждой ячейке - запомните их!!! например, вы можете создать изображение маски, равное 0 на всех пикселях, кроме тех, которые были выбраны как "белые"
Фильтруйте цвета ячеек, локально подбирая плоскость в пространстве RGB.
Теперь вернитесь в пространство RBG. как видите, доска становится темнее, когда она уходит. если вы нанесете цвета RGB пикселей на белой доске как 3d-точки в трехмерном мире, оси которого R,G и B, вы получите разброс, который приблизительно равен плоскости (поскольку все эти цвета белой доски имеют серый оттенок), Теперь возьмите точки, которые вы отметили как "доска" на предыдущем шаге, и подгоните к ним плоскость. Как посадить самолет? Вы можете использовать метод наименьших квадратов, но, как они написали в статье, я думаю, что они имели в виду RANSAC.