How to detect and extract text from the box model forms - python-3.x

import cv2
import numpy as np
from boxdetect import config
from boxdetect.pipelines import get_boxes
import matplotlib.pyplot as plt
image1 = cv2.imread('kyc_sample1.jpg')
img = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
ret, thresh4 = cv2.threshold(img, 120, 255, cv2.THRESH_TOZERO)
cv2.imshow('Kyc', thresh4)
cfg = config.PipelinesConfig()
cfg.width_range = (30,55)
cfg.height_range = (25,40)
cfg.scaling_factors = [0.7]
cfg.wh_ratio_range = (0.5, 1.7)
cfg.group_size_range = (2, 100)
cfg.dilation_iterations = 0
rects, grouping_rects, image, output_image = get_boxes(
thresh4, cfg=cfg, plot=False)
print(grouping_rects)
plt.figure(figsize=(20,20))
plt.imshow(output_image)
plt.show()
Required solution:
Name: Mr William Smith Jons , PAN: 577634563744
Is there any solution to detect the text from the box and extract the text based on the detection of boxes. I have used boxdetection method in python to detect the text form the form

Related

why does opencv threshold returns absurd output on a very simple image?

I am trying to count seeds in an image using cv2 thresholding. The test image is below:
When I run the below code to create a mask:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('S__14278933.jpg')
#img = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
mask = cv2.threshold(img[:, :, 0], 255, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
plt.imshow(mask)
I get the following mask:
But ideally it should give a small yellow dot at the centre. I have tried this with other images and it works just fine.
Can someone help?
The lighting in your image seems not uniform. Try using Adaptive Thresholding:
import cv2
import numpy as np
# image path
path = "D://opencvImages//"
fileName = "c6pBO.jpg"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Convert the image to grayscale:
grayImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Get binary image via Adaptive Thresholding :
windowSize = 31
windowConstant = 40
binaryImage = cv2.adaptiveThreshold( grayImage, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY_INV, windowSize, windowConstant )
cv2.imshow("binaryImage", binaryImage)
cv2.waitKey(0)
You might want to apply an Area Filter after this, though, as dark portions on the image will yield noise.
Try it
img=cv2.imread('foto.jpg',0)
mask = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV )[1]

how do I extract all pixel values from a certain ROI and then store it as a CSV file and again use that csv file to get back that ROI

After applying mask original image
import cv2
import dlib
import numpy as np
img = cv2.imread("Aayush.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
msk = np.zeros_like(img_gray)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
faces = detector(img_gray)
for face in faces:
landmarks = predictor(img_gray, face)
lp = []
for n in range(0,68):
x = landmarks.part(n).x
y = landmarks.part(n).y
lp.append((x,y))
p = np.array(lp, np.int32)
#cv2.circle(img, (x,y), 3, (0, 0, 255), -1)
convexhull = cv2.convexHull(p)
#cv2.polylines(img, [convexhull], True, (255,0,0), 3)
cv2.fillConvexPoly(msk, convexhull, 255)
img1 = cv2.bitwise_and(img, img, mask = msk)
img1 containsa complete black image with face cut from img, I just require the pixel values of face portion and not complete image
As original image and mask have not been provided in the question itself. I am assuming a simple input image and a mask image with circular cavity as:
The mask here is a single channel matrix with a value of 255 in the central cavity. To get the pixel info inside the cavity only you can use following numpy operation:
pixel_info = original_image[mask == 255]
# You may need to convert the numpy array to Python list.
pixel_info_list = pixel_info.tolist()
Now you may serialize the list to any format you want (csv in this case.)
Full code:
import cv2
import numpy as np
original_image = cv2.imread("/path/to/lena.png")
mask = np.zeros(original_image.shape[:2], dtype=original_image.dtype)
mask = cv2.circle(mask, (256, 256), 100, [255], -1)
pixel_info = original_image[mask == 255]
pixel_info_list = pixel_info.tolist()

How to make image more contrast, grayscale then get all characters exactly with PIL and pytesseract?

PLease download the attatchment here and save it as /tmp/target.jpg.
You can see that there are 0244R in the jpg,i extract string with below python code:
from PIL import Image
import pytesseract
import cv2
filename = "/tmp/target.jpg"
image = cv2.imread(filename)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray,55, 255, cv2.THRESH_BINARY)
print(pytesseract.image_to_string(threshold))
What I get is
0244K
The right string is 0244R,how to make image more contrast, grayscale then get all characters exactly with with PIL and pytesseract?
Here is the webpage which generate the image :
http://www.crup.cn/ValidateCode/Index?t=0.14978241776661583
If you apply adaptive-thresholding and bitwise-not operations to the input image, the result will be:
Now if you remove the special characters like (dot, comma, etc..)
txt = pytesseract.image_to_string(bnt, config="--psm 6")
res = ''.join(i for i in txt if i.isalnum())
print(res)
Result will be:
O244R
Code:
import cv2
import pytesseract
img = cv2.imread("Aw6sN.jpg")
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY_INV, 23, 100)
bnt = cv2.bitwise_not(thr)
txt = pytesseract.image_to_string(bnt, config="--psm 6")
res = ''.join(i for i in txt if i.isalnum())
print(res)

Python - Read an image from URL to resize and convert image to grayscale

I want to read an image from URL to resize and convert it to grayscale. I have seen a number of examples from stackoverflow and I tried them out. However, it never successfully converts image to grayscale in my case. I'm not sure what went wrong here. This are what I tried.
import matplotlib.pyplot as plt
from skimage.transform import resize
import numpy as np
from skimage import io, color
# try 1
img1 = io.imread("https://prasadpamidi.github.io/images/image2.jpg", as_grey=True)
img1 = (img1 - 255.0) / 255
img1 = resize(img1, (32, 32))
# try 2
img1 = io.imread("https://prasadpamidi.github.io/images/image2.jpg")
img1 = img1.dot([0.07, 0.72, 0.21])
img1 = (img1 - 255.0) / 255
img1 = resize(img1, (32, 32))
# try 3
img1 = color.rgb2gray(io.imread("https://prasadpamidi.github.io/images/image2.jpg"))
img1 = (img1 - 255.0) / 255
img1 = resize(img1, (32, 32))
# print images
plt.figure(figsize=(5,5))
plt.imshow(img1)
plt.show()
The result more or less is similar to below. So, I'd like to know what I missed. Any suggestions will be appreciated.
Give this code a try:
from skimage.io import imread, imshow
from skimage.transform import resize
from skimage.util import img_as_ubyte
url = "https://prasadpamidi.github.io/images/image2.jpg"
img1 = imread(url, as_gray=True)
img2 = resize(img1, (32, 32))
img3 = img_as_ubyte(img2)
imshow(img3)
Output:
I'm attaching a screenshot of the variable explorer to show you that the variables have the correct shape and type.

Image Cropping to get just the particular shape out of image

[I have the images as below, i need to extract just the white strip portion from all the images.
i Have tried using PIL to extract the rectangular portion by manually specifying the pixel value, Can there be any automated way to get this work done where by just feeding the image gives back the rectangular portion
Below is My snipped code:
from PIL import Image
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = Image.open('C:/Users/ShAgarwal/Documents/image_dataset/pic9.jpg')
half_the_width = img.size[0] / 2
half_the_height = img.size[1] / 2
img4 = img.crop(
(
half_the_width-1632,
half_the_height - 440,
half_the_width+1632,
half_the_height + 80
)
)
sample image
import cv2
import numpy as np
from matplotlib import pyplot as plt
image='IMG_3134.JPG'
# read image
imgc = cv2.imread(image)
img = cv2.resize(imgc, None, fx=0.25, fy=0.25) # resize since image is huge
#cropping the strip dimensions
#crop_img = img[1010:1650,140:1099723]
blurred = cv2.blur(img, (3,3))
canny = cv2.Canny(blurred, 50, 200)
Marking coordinates through auto image detection using canny's algorithm
## find the non-zero min-max coords of canny
pts = np.argwhere(canny>0)
y1,x1 = pts.min(axis=0)
y2,x2 = pts.max(axis=0)`
`## crop the region
cropped = img[y1:y2, x1:x2]
cv2.imwrite("cropped.png", cropped)
#Select the bounded area around white boundary
tagged = cv2.rectangle(img.copy(), (x1,y1), (x2,y2), (0,255,0), 3, cv2.LINE_AA)
r = cv2.selectROI(tagged)
imCrop = im[int(r[1]):int(r[1]+r[3]), int(r[0]):int(r[0]+r[2])]
#Bounded Area
cv2.imwrite("taggd2.png", imcrop)
cv2.waitKey()
Results from above code

Resources