I have an image of size 3500×5000, now I want to detect only the table part from the entire image and crop and rotate it if it is not straight for OCR processing. After all search, I get an idea for cropping each cell in an image using https://medium.com/coinmonks/a-box-detection-algorithm-for-any-image-containing-boxes-756c15d7ed26 , but don’t know how to crop the table part in an image.
The image I used here:
now I want only this part like this:(manually cropped)
Thanks in advance!..
Advertisement
Answer
@user:12894468, @user:5404226 After a long search I came to found a best approch to find only table in images using DETECTRON2 https://github.com/facebookresearch/detectron2 but it works only in lunix environment, I used windows subsystem for lunix, here I used this code for several images placed in folder and create each folder(may image contains one or more table) with the file name
import uuid
# Some basic setup:
# Setup detectron2 logger
import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()
# import some common libraries
import numpy as np
import os, json, cv2, random
#from google.colab.patches import cv2_imshow
# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog
from detectron2.engine import DefaultTrainer
from detectron2.structures import BoxMode
from detectron2.utils.visualizer import ColorMode
ROOT_DIR = "./"
ipdir = ROOT_DIR + "nswtable_input/image/"
opdir = ROOT_DIR + "results_nswtable/"
def predict(im, item):
fileName=item
outputs = predictor(im)
v = Visualizer(im[:, :, ::-1],
metadata=balloon_metadata,
scale=0.8,
instance_mode=ColorMode.IMAGE_BW # remove the colors of unsegmented pixels
)
v = v.draw_instance_predictions(outputs["instances"].to("cpu"))
#print(outputs["instances"].pred_boxes.tensor.numpy())
path = "/root/images/"
path1="/root/tblImg/"
cv2.imwrite(path1 + fileName + ".png", v.get_image()[:, :, ::-1])
boxes = {}
file = os.path.join(path,fileName)
try:
f=os.makedirs(file,exist_ok=True)
print("Directory '%s' created " % file)
except OSError as error:
print("cannot create"%directory)
i=1
coords=[]
for coordinates in outputs["instances"].to("cpu").pred_boxes:
coordinates_array = []
for k in coordinates:
coordinates_array.append(int(k))
boxes[uuid.uuid4().hex[:].upper()] = coordinates_array
coords.append(coordinates_array)
for k,v in boxes.items():
crop_img = im[v[1]:v[3], v[0]:v[2], :]
#print(v[1],v[3], v[0],v[2])
#cv2_imshow(crop_img)
crop_width,crop_height=crop_img.shape[0],crop_img.shape[1]
if crop_width>crop_height:
img_rot=cv2.rotate(crop_img,cv2.ROTATE_90_CLOCKWISE)
#------for naming the images------#v[1]=y,v[3]=y+h, v[0]=x,v[2]=x+w
margin = 0
ymin = max(v[1]-margin,0)
ymax =v[3]+margin
xmin = max(v[0] - margin,0)
xmax = v[2]+margin
#print(ymin,ymax,xmin,xmax)
cv2.imwrite(file+'/'+str(i)+'_'+str(xmin)+'_'+str(ymin)+'_'+str(xmin)+'_'+str(ymax)+'_'+str(xmax)+'_'+str(ymin)+'_'+str(xmax)+'_'+str(ymax)+ '.png', img_rot)
i=i+1
return outputs
dirs = os.listdir(ipdir)
for item in dirs:
if os.path.isfile(ipdir+item):
im = cv2.imread(ipdir+item)
print(item)
f, e = os.path.splitext(ipdir+item)
#width,height = im.shape[1],im.shape[0]
item = item[:-4]
predict(im, item)
the output I get as below:
https://ibb.co/0Q16Gyv
Use the above mentioned link for how to train the sample and others