I am looking for pupil detection from image using pythonwith opencvpackage. In my test images, I am able to detect pupil in (a) part but whenever there is a presence of reflection/ glare, I am unable to detect blob of pupil pixels accurately in (b) part of image. Can anybody help me out? Here is the code I am trying.
import numpy as np
import cv2
name = 'two_eyes1.png'
# reading an image
img = cv2.imread(name, cv2.IMREAD_COLOR)
# inverting image
img_inv = cv2.bitwise_not(img)
gray = cv2.cvtColor(img_inv, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY)
#----- Blob detector parameters initiation
params = cv2.SimpleBlobDetector_Params()
#change thresholds
params.minThreshold = 0;
params.maxThreshold = 255;
#filter by area
params.filterByArea = True
params.minArea = 70
# filter by cicularity
params.filterByCircularity = True
params.minCircularity = 0.1
# filter by convexity
params.filterByConvexity = True
params.minConvexity = 0.87
# filter by inertia
params.filterByInertia = True
params.minInertiaRatio = 0.01
det = cv2.SimpleBlobDetector_create(params)
keypoints = det.detect(img)
im_with_key = cv2.drawKeypoints(img, keypoints, np.array([]),
(0,0,255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#----------
titles = ['Input','Inverted','Grayscaled','Thresholded','blobpart']
images = [img, img_inv, gray, threshold, im_with_key]
for i in range(5):
cv2.imshow(titles[i], images[i])
cv2.waitKey(0)
cv2.destroyAllWindows()
Related
I am using tesseract 5.3.0 With the code below I am able to identify the licence plate and mask it out, however when I resize the licence plate part does not increase. How do I grab just the licence portion and increase it? Any tips on reading the licence plate would also be appreciated.
import cv2
import numpy as np
import imutils
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'/usr/local/bin/tesseract'
# Load the image and convert it to grayscale
image = cv2.imread('/Users/PythonProg/IMG_4592.JPG')
if image is None:
print("Error: Could not load the image")
exit()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Gaussian Blur to reduce noise and smooth the image
gray = cv2.bilateralFilter(gray, 13, 15, 15)
edged = cv2.Canny(gray, 30, 200)
contours = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None
# Loop over the contours and find the one with the largest area
licence_plate = None
for c in contours:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.018 * peri, True)
if len(approx) == 4:
screenCnt = approx
break
if screenCnt is None:
detected = 0
print ("No contour detected")
else:
detected = 1
if detected == 1:
cv2.drawContours(image, [screenCnt], -1, (0, 0, 255), 3)
cv2.imwrite('/Users/PythonProg/output.jpg', image)
mask = np.zeros(gray.shape,np.uint8)
licence_plate = cv2.drawContours(mask,[screenCnt],0,255,-1,)
licence_plate = cv2.bitwise_and(image,image,mask=mask)
cv2.imwrite('/Users/anthonywilson/PythonProg/mask.jpg', licence_plate)
# Resize the masked image to a specific size
resized = cv2.resize(licence_plate, (400, 200), interpolation = cv2.INTER_AREA)
# Save the resized image
cv2.imwrite('/Users/PythonProg/resized.jpg', resized)
output
input
I'm trying to isolate the iris but the pupil gets isolated in a circle, how can I change it so it surrounds the iris and not the pupil. Also i using stock jpeg files. I tried a lot of stuff but I'm really new to opencv and image processing so any help would be admirable. Also in some images it makes a circle in very weird places which makes me think something else is also up with the code.
#import numpy
import cv2
import numpy as np
class pupil_detection():
def __init__(self, image_path):
'''
initialize the class and set the class attributes
'''
self._img = None
self._img_path = image_path
self._pupil = None
self._centroid = None
def load_image(self):
'''
load the image based on the path passed to the class
it should use the method cv2.imread to load the image
it should also detect if the file exists
'''
self._img = cv2.imread(self._img_path)
#self._img = cv2.resize(self._img, (300,300))
# If the image doesn't exists or is not valid then imread returns None
if type(self._img) == None:
return False
else:
return True
def show_image (self,img):
cv2.imshow("Result",img)
cv2.waitKey(0)
def centroid (self):
# convert image to grayscale image
gray_image = cv2.cvtColor(self._img, cv2.COLOR_BGR2GRAY)
# convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0)
# calculate moments of binary image
M = cv2.moments(thresh)
# calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
self._centroid = (cX,cY)
cv2.circle(self._img, (cX, cY), 5, (255, 255, 255), -1)
def detect_pupil (self):
dst = cv2.fastNlMeansDenoisingColored(self._img,None,10,10,7,21)
blur = cv2.GaussianBlur(dst,(5,5),0)
inv = cv2.bitwise_not(blur)
thresh = cv2.cvtColor(inv, cv2.COLOR_BGR2GRAY)
kernel = np.ones((2,2),np.uint8)
erosion = cv2.erode(thresh,kernel,iterations = 1)
ret,thresh1 = cv2.threshold(erosion,210,255,cv2.THRESH_BINARY)
cnts, hierarchy = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
flag = 10000
final_cnt = None
for cnt in cnts:
(x,y),radius = cv2.minEnclosingCircle(cnt)
distance = abs(self._centroid[0]-x)+abs(self._centroid[1]-y)
if distance < flag :
flag = distance
final_cnt = cnt
else:
continue
(x,y),radius = cv2.minEnclosingCircle(final_cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(self._img,center,radius,(255,0,0),2)
self._pupil = (center[0],center[1],radius)
self.show_image(self._img)
def start_detection(self):
if(self.load_image()):
self.centroid()
self.detect_pupil()
else:
print('Image file "' + self._img_path + '" could not be loaded.')
id = pupil_detection(r'rightlook2.jpg')
id.start_detection()
I need a hand to be able to fix my project with opencv, which consists in detecting plates and using tesseract to extrapolate the content, but I don't understand why only the text written on a white background detects me and not when I use a real plate. I tried to arrange the image in order to make it more legible and maybe frame only the white part of the European license plates in order to simplify the extrapolation of the text, but nothing I can not isolate only the white. I using a raspberry pi 4, i don't know if it can be useful
Could anyone help me? Many thanks in advance.
print("Aspetta 5 secondi per catturare l'immagine, oppure premi <space> per scattare...")
cam = cv2.VideoCapture(0)
num_frames = 0
while True:
ret, image = cam.read()
if not ret:
print("La webcam non funziona...")
sys.exit(1)
cv2.imshow('image', image)
# Catturo l'immagine se premo <space>
if (cv2.waitKey(1) & 0xFF) == ord(' '):
break
# Aspetto 5 secondi prima di catturare l'immagine
num_frames += 1
if num_frames / 10 == 5:
break
cam.release()
cv2.destroyAllWindows()
cv2.imwrite("/home/pi/Desktop/Riconoscimento Targa/imagee.jpg", image)
filename = 'imagee.jpg'
img = np.array(Image.open(filename))
img = cv2.resize(img, (600,400) )
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 13, 15, 15)
edged = cv2.Canny(gray, 30, 200) #Perform Edge detection
contours=cv2.findContours(edged.copy(),cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
contours = sorted(contours,key=cv2.contourArea, reverse = True)[:10]
screenCnt = None
for c in contours:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.018 * peri, True)
# if our approximated contour has four points, then
# we can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break
# Masking the part other than the number plate
mask = np.zeros(gray.shape,np.uint8)
new_image = cv2.drawContours(mask,[screenCnt],0,255,-1,)
new_image = cv2.bitwise_and(img,img,mask=mask)
# Now crop
(x, y) = np.where(mask == 255)
(topx, topy) = (np.min(x), np.min(y))
(bottomx, bottomy) = (np.max(x), np.max(y))
Cropped = gray[topx:bottomx+1, topy:bottomy+1]
cv2.imwrite("/home/pi/Desktop/Riconoscimento Targa/Da eliminare.jpg", Cropped)
text = pytesseract.image_to_string(Cropped, config='--psm 11 -l ita')
return text
I am attempting to count the dark objects in the first image. I've been working with the supplied code using the SimpleBlobDetector (found here on SO), but can't seem to work out how to reliably count each object. As images can be taken from varying heights, the min/maxAreas vary greatly. However, the backgrounds are always white.
Before
After
#!/usr/bin/env python3
import cv2
import numpy as np
def ResizeWithAspectRatio(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
return cv2.resize(image, dim, interpolation=inter)
# Read image
im = cv2.imread("image7-1.jpg", cv2.IMREAD_GRAYSCALE)
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 10
params.maxThreshold = 200
# Filter by Area.
params.filterByArea = True
params.minArea = 80
params.maxArea = 450
# Filter by Circularity
params.filterByCircularity = False
params.minCircularity = 0.1
# Filter by Convexity
params.filterByConvexity = False
params.minConvexity = 0.87
# Filter by Inertia
params.filterByInertia = False
params.minInertiaRatio = 0.01
# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
detector = cv2.SimpleBlobDetector(params)
else:
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
print(len(keypoints))
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imwrite("result.png",im_with_keypoints)
resize = ResizeWithAspectRatio(im_with_keypoints, width=900)
cv2.imshow("Result",resize)
cv2.waitKey(0)
I can do this extremely reliably in MatLab with ~98% accuracy. However, I really want to port this into python. Any ideas on what I can do to produce better/more accurate results?:
Rmin = 6;
Rmax = 15;
color = imread('image7.jpg');
grayImage=rgb2gray(color);
imshow(color), title('Image');
[centersNew, radiiNew] = imfindcircles(grayImage,[Rmin Rmax],'ObjectPolarity','dark','Sensitivity',0.965);
[centersNew,radiiNew] = RemoveOverLap(centersNew,radiiNew,5,1);
viscircles(centersNew,radiiNew, 'EdgeColor','r');
numel(radiiNew)
Result
I have an image that converted from PDF to PNG. The converted image contains several keywords that I wanted to extracted using OCR Tesseract.
Right now, I need to determine the ROI manually to crop the selected ROI. Since I have more than 5 ROI's to be applied, what would be the most efficient way to apply the ROI instead of doing it by try and error to find the exact location?
Below is the code:
def cropped(self, event):
#1st ROI
y = 20
x = 405
h = 230
w = 425
#2nd ROI
y1 = 30
x1 = 305
h1 = 330
w1 = 525
#open the converted image
image = cv2.imread("Output.png")
#perform image cropping
crop_image = image[x:w, y:h]
crop_image1 = image[x1:w1, y1:h1]
#save the cropped image
cv2.imwrite("Cropped.png", crop_image)
cv2.imwrite("Cropped1.png", crop_image1)
#open the cropped image and pass to the OCR engine
im = cv2.imread("Cropped.png")
im1 = cv2.imread("Cropped1.png")
## Do the text extraction here
you can use mouse event to select multiple ROI and crop based on the location
#!/usr/bin/env python3
import argparse
import cv2
import numpy as np
from PIL import Image
import os
drawing = False # true if mouse is pressed
ix,iy = -1,-1
refPt = []
img = ""
clone = ""
ROIRegion = []
# mouse callback function
def draw_rectangle(event,x,y,flags,param):
global ix,iy,drawing,img,clone,refPt, ROIRegion
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix,iy = x,y
refPt = [(x, y)]
ROIRegion.append(refPt)
#clone = img.copy()
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
img = clone.copy()
cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),3)
a=x
b=y
if a != x | b != y:
cv2.rectangle(img,(ix,iy),(x,y),(0,0,0),-1)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
refPt.append((x,y))
img = clone.copy()
cv2.rectangle(img, (ix,iy),(x,y), (0, 255, 0), 2)
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# load the image, clone it, and setup the mouse callback function
img = cv2.imread(args["image"])
img = np.array(img)
clone = img.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_rectangle)
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == ord("r"):
del ROIRegion[-1]
del refPt[-1]
img = clone.copy()
elif k == 27:
break
#Do your cropping here
for region in range(len(ROIRegion)):
cv2.rectangle(img, ROIRegion[region][0],ROIRegion[region][1], (0, 255, 0), 2)
roi = clone[ROIRegion[region][0][1]:ROIRegion[region][1][1], ROIRegion[region][0][0]:ROIRegion[region][1][0]]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
Here is one way in Python/OpenCV.
Read the input
Threshold on box outline color
Apply morphology to ensure closed
Get the external contours
Loop over each contour, get its bounding box, crop the region in the input and write the output
Input:
import cv2
import numpy as np
# read image
img = cv2.imread('text_boxes.jpg')
# threshold on box outline color
lowerBound = (80,120,100)
upperBound = (160,200,180)
thresh = cv2.inRange(img, lowerBound, upperBound)
# apply morphology to ensure regions are filled and remove extraneous noise
kernel = np.ones((3,3), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# get contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
# get bounding boxes
i = 1
for cntr in contours:
# get bounding boxes
x,y,w,h = cv2.boundingRect(cntr)
crop = img[y:y+h, x:x+w]
cv2.imwrite("text_boxes_crop_{0}.png".format(i), crop)
i = i + 1
# save threshold
cv2.imwrite("text_boxes_thresh.png",thresh)
# show thresh and result
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
Threshold image:
Cropped Images: