Improved line finding

This commit is contained in:
Caesar2011
2019-03-20 22:20:17 +01:00
parent 56d526d00f
commit 516efb0d37
3 changed files with 40 additions and 18 deletions

10
main.py
View File

@@ -1,18 +1,20 @@
import glob import glob
import os import os
from src.processing.loader import load_image, save_image from src.processing.loader import load_image
from src.processing.linefinder import find_lines, preparation from src.processing.linefinder import find_lines
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from src.processing.receiptcutter import cut_receipt from src.processing.receiptcutter import cut_receipt
for root, dirs, files in os.walk("data"): for root, dirs, files in os.walk("data"):
for file in files: for file in files:
if file.startswith("receipt-08"): if file.startswith("receipt-12"):
image = load_image("data/"+file) image = load_image("data/"+file)
receipt = cut_receipt(image, draw_steps=True) receipt = cut_receipt(image, draw_steps=True)
lines = find_lines(receipt) lines = find_lines(receipt, draw_steps=True)
print("hh", len(lines))
#continue
for line in lines: for line in lines:
plt.imshow(line, cmap="gray") plt.imshow(line, cmap="gray")
plt.show() plt.show()

View File

@@ -3,8 +3,12 @@ from scipy.ndimage import measurements
from src.processing.imageprocessing import rgb2gray from src.processing.imageprocessing import rgb2gray
from matplotlib import pyplot as plt
def find_lines(image): from src.utils.cmap_generator import rand_cmap
def find_lines(image, draw_steps=False):
gray, binary, magnitude = preparation(image) gray, binary, magnitude = preparation(image)
#backtrack = load_numpy("result/backtrack.npz") #backtrack = load_numpy("result/backtrack.npz")
#if backtrack is None: #if backtrack is None:
@@ -12,7 +16,7 @@ def find_lines(image):
#save_numpy("result/backtrack.npz", backtrack) #save_numpy("result/backtrack.npz", backtrack)
seams = calculate_seams(backtrack) seams = calculate_seams(backtrack)
labeled, ncomponents = group_empty_boxes(seams) labeled, ncomponents = group_empty_boxes(seams)
lines = generate_lines(labeled, ncomponents, gray) lines = generate_lines(labeled, ncomponents, gray, draw_steps)
return filter_lines(lines) return filter_lines(lines)
@@ -102,9 +106,14 @@ def group_empty_boxes(seams):
return labeled, ncomponents return labeled, ncomponents
def generate_lines(labeled, ncomponents, gray): def generate_lines(labeled, ncomponents, gray, draw_steps=False):
if draw_steps:
plt.imshow(labeled, cmap=rand_cmap(ncomponents+1, "hard"))
plt.title("Found line groups")
plt.show()
groups = np.copy(labeled) groups = np.copy(labeled)
group_id = 1 group_id = 0
entries = [] entries = []
pixelgroup = None pixelgroup = None
in_top_mode = True in_top_mode = True
@@ -113,11 +122,12 @@ def generate_lines(labeled, ncomponents, gray):
def submit_entry(): def submit_entry():
nonlocal pixelgroup, group_id, entries nonlocal pixelgroup, group_id, entries
group_id += 1
minps = np.min(pixelgroup, axis=0) minps = np.min(pixelgroup, axis=0)
maxps = np.max(pixelgroup, axis=0) maxps = np.max(pixelgroup, axis=0)
if pixel.shape[0] < 20 or maxps[1] - minps[1] < 5 or maxps[0] - minps[0] < 5:
return
entry = gray[minps[1]:maxps[1] + 1, minps[0]:maxps[0] + 1] entry = gray[minps[1]:maxps[1] + 1, minps[0]:maxps[0] + 1]
if pixelgroup.shape[0] < 20 or maxps[1] - minps[1] < 5 or maxps[0] - minps[0] < 5:
return
if pixelgroup.shape[0] / entry.shape[0] / entry.shape[1] < 0.10: if pixelgroup.shape[0] / entry.shape[0] / entry.shape[1] < 0.10:
return return
pixelgroup = np.subtract(pixelgroup, minps) pixelgroup = np.subtract(pixelgroup, minps)
@@ -131,7 +141,6 @@ def generate_lines(labeled, ncomponents, gray):
#white[pixelgroup[:, 1], pixelgroup[:, 0]] = entry[pixelgroup[:, 1], pixelgroup[:, 0]] #white[pixelgroup[:, 1], pixelgroup[:, 0]] = entry[pixelgroup[:, 1], pixelgroup[:, 0]]
entries.append(white) entries.append(white)
pixelgroup = None pixelgroup = None
group_id += 1
for label in range(1, ncomponents+1): for label in range(1, ncomponents+1):
pixel = indices[labeled == label] pixel = indices[labeled == label]
@@ -149,21 +158,30 @@ def generate_lines(labeled, ncomponents, gray):
in_top_mode = False in_top_mode = False
if pixelgroup is not None and minp[1] - 5 > np.max(pixelgroup, axis=0)[1]: if pixelgroup is not None and minp[1] - 5 > np.max(pixelgroup, axis=0)[1]:
submit_entry() submit_entry()
groups[labeled == label] = group_id groups[labeled == label] = group_id+1
if pixelgroup is None: if pixelgroup is None:
pixelgroup = pixel[:, :] pixelgroup = pixel[:, :]
else: else:
pixelgroup = np.concatenate((pixelgroup, pixel)) pixelgroup = np.concatenate((pixelgroup, pixel))
submit_entry() submit_entry()
if draw_steps:
plt.imshow(groups, cmap=rand_cmap(group_id+1, "hard"))
plt.title("Combined and valid groups")
plt.show()
return entries return entries
def filter_lines(lines): def filter_lines(lines):
filtered = [] filtered = []
for line in lines: for line in lines:
cnt, vals = np.histogram(line, 256) cnt, vals = np.histogram(line, 256)
threshold = get_threshold(cnt)/256*1.13#*0.96 threshold = get_threshold(cnt)/256*0.96
binary = (line > threshold).astype(np.int_) binary = (line > threshold).astype(np.int_)
labeled, ncomponents = group_empty_boxes(binary) labeled, ncomponents = group_empty_boxes(binary)
if ncomponents > 2: count = 0
for label in range(1, ncomponents+1):
pixcnt = np.sum(labeled == label)
if pixcnt > 10:
count += 1
if count > 2:
filtered.append(line) filtered.append(line)
return filtered return filtered

View File

@@ -3,6 +3,8 @@ from collections import defaultdict
from skimage.transform import resize from skimage.transform import resize
from scipy.ndimage import gaussian_filter from scipy.ndimage import gaussian_filter
from matplotlib import pyplot as plt
from src.processing.imageprocessing import rgb2gray_value from src.processing.imageprocessing import rgb2gray_value
from scipy import signal from scipy import signal
import numpy as np import numpy as np
@@ -161,8 +163,8 @@ def draw_hough_lines(image, scale, results, references, shape, theta_res=5, widt
y = int(n - x * m) y = int(n - x * m)
if 0 < y < image.shape[0]: if 0 < y < image.shape[0]:
draw_image[max(0, y - GREEN_WIDTH):y + GREEN_WIDTH, max(0, x - GREEN_WIDTH):x + GREEN_WIDTH] = np.array([255, 0, 0]) draw_image[max(0, y - GREEN_WIDTH):y + GREEN_WIDTH, max(0, x - GREEN_WIDTH):x + GREEN_WIDTH] = np.array([255, 0, 0])
#plt.imshow(draw_image) plt.imshow(draw_image)
#plt.show() plt.show()
def convert_to_lines(scale, results, references, shape, theta_res=5, width_res=5): def convert_to_lines(scale, results, references, shape, theta_res=5, width_res=5):
@@ -342,8 +344,8 @@ def draw_rectangle(image, corners):
x = int(a[1] + (b[1] - a[1]) * i / 5000) x = int(a[1] + (b[1] - a[1]) * i / 5000)
y = int(a[0] + (b[0] - a[0]) * i / 5000) y = int(a[0] + (b[0] - a[0]) * i / 5000)
draw_image[max(0, y - 15):y + 10, max(0, x - 10):x + 10] = np.array([255, 0, 0]) draw_image[max(0, y - 15):y + 10, max(0, x - 10):x + 10] = np.array([255, 0, 0])
#plt.imshow(draw_image) plt.imshow(draw_image)
#plt.show() plt.show()
def crop_image(image, corners): def crop_image(image, corners):