SVM always gives the same prediction - python

I have a page and I am trying to predict letters on the page by using SVM. However, the prediction result always the same. As a result, I am unable to read the page.
This is my code to detect the letters from the line images(I separated lines before):
def letters(img):
rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
morph_letters = cv2.morphologyEx(img, cv2.MORPH_CROSS, rect_kernel)
cv2.imshow("morph", morph_letters)
cnts = cv2.findContours(morph_letters.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
lengthOfContours = len(cnts)
print("Number of counturs: ", lengthOfContours)
points = []
rects = []
for (i, c) in enumerate(cnts):
area = cv2.contourArea(c)
if area > 80:
print("area "+str(area))
(x, y, w, h) = cv2.boundingRect(c)
x = x - 3
y = y - 10
w = w + 4
h = h + 12
cv2.rectangle(img_letters, (x, y), (x + w, y + h), (0, 255, 0), 2)
rect = [x, y, w+x, h+y]
leftPoint = x
#print("leftPoint: ", leftPoint)
points.append(leftPoint)
points.sort()
rects.append([i,rect])
rects.sort(key=lambda x: x[1])
#print("rects: ", rects)
if i == lengthOfContours-1:
for i in range(len(rects)):
found_letter = thresh_adaptive[rects[i][1][1]:rects[i][1][3], rects[i][1][0]:rects[i][1][2]]
prediction(found_letter)
And this is my prediction code. It takes the letter image from def letters function, name: found_letter. However, the result is always the same, l.
def prediction(word_img):
pick = open('model-letters.sav', 'rb')
#pickle.dump(model, pick)
model = pickle.load(pick)
pick.close()
#prediction = model.predict(x_test)
#accuracy = model.score(x_test, y_test)
categories = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J', 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4', '5','6','7','8','9','0']
img = word_img
try:
img = cv2.resize(img, (50,50))
img = np.array(img).flatten()
img = img.reshape(1, -1)
print("working")
prediction = model.predict(img)
letter = categories[prediction[0]]
print("Prediction ", prediction)
print("Prediction letter: ", letter)
#print("Accuracy: ",accuracy)
letterImg = img
cv2.imshow("letter", letterImg)
cv2.waitKey(0)
fh = open("letters.txt", "a")
fh.write(letter)
fh.close()
except:
print("error")
And this is my for loop to gives all the line images to def letters(img) function.
index = -1
for i in range(30,-1,-1):
index = index + 1
dir = "images-lines2/line" + str(i) + ".png"
img_orj = cv2.imread(dir)
img_orj = cv2.resize(img_orj, None, fx=1, fy=1.5, interpolation=cv2.INTER_AREA)
img_letters = img_orj.copy()
gray = cv2.cvtColor(img_orj, cv2.COLOR_BGR2GRAY)
img_lines = img_orj.copy()
blur_gaus = cv2.GaussianBlur(gray,(3,3),0)
kernel = np.ones((3,3), np.uint8)
thresh_adaptive = cv2.adaptiveThreshold(blur_gaus,255,cv2. ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV,7,11)
letter_img = letters(thresh_adaptive)
If you want to see cv2.imshow("letter", letterImg), this is the
output
Any help is appreciated.

Related

AttributeError: module 'tensorflow.core.framework.types_pb2' has no attribute 'SerializedDType'

`import cv2
import numpy as np
import time
from tensorflow.keras.models import load_model
sign_model = load_model('best_model.h5')
def detect_lines(image):
tuning min_threshold, minLineLength, maxLineGap is a trial and error process by hand
rho = 1 # precision in pixel, i.e. 1 pixel
angle = np.pi / 180 # degree in radian, i.e. 1 degree
min_threshold = 10 # minimal of votes
lines = cv2.HoughLinesP(image, rho, angle, min_threshold, np.array([]), minLineLength=8,
maxLineGap=4)
return lines
def mean_lines(frame, lines):
a = np.zeros_like(frame)
try:
left_line_x = []
left_line_y = []
right_line_x = []
right_line_y = []
for line in lines:
for x1, y1, x2, y2 in line:
slope = (y2 - y1) / (x2 - x1) # <-- Calculating the slope.
if abs(slope) < 0.5: # <-- Only consider extreme slope
continue
if slope <= 0: # <-- If the slope is negative, left group.
left_line_x.extend([x1, x2])
left_line_y.extend([y1, y2])
else: # <-- Otherwise, right group.
right_line_x.extend([x1, x2])
right_line_y.extend([y1, y2])
min_y = int(frame.shape[0] * (3 / 5)) # <-- Just below the horizon
max_y = int(frame.shape[0]) # <-- The bottom of the image
poly_left = np.poly1d(np.polyfit(
left_line_y,
left_line_x,
deg=1
))
left_x_start = int(poly_left(max_y))
left_x_end = int(poly_left(min_y))
poly_right = np.poly1d(np.polyfit(
right_line_y,
right_line_x,
deg=1
))
right_x_start = int(poly_right(max_y))
right_x_end = int(poly_right(min_y))
cv2.line(a, (left_x_start, max_y), (left_x_end, min_y), [255,255,0], 5)
cv2.line(a, (right_x_start, max_y), (right_x_end, min_y), [255,255,0], 5)
current_pix = (left_x_end+right_x_end)/2
except:
current_pix = 128
return a, current_pix
def region_of_interest(image):
(height, width) = image.shape
mask = np.zeros_like(image)
polygon = np.array([[
(0, height),
(0, 180),
(80, 130),
(256-80,130),
(width, 180),
(width, height),
np.int32)
cv2.fillPoly(mask, polygon, 255)
masked_image = image * (mask)
masked_image[:170,:]=0
return masked_image
def horiz_lines(mask):
roi = mask[160:180, 96:160]
try:
lines = detect_lines(roi)
lines = lines.reshape(-1,2,2)
slope = (lines[:,1,1]-lines[:,0,1]) / (lines[:,1,0]-lines[:,0,0])
if (lines[np.where(abs(slope)<0.2)]).shape[0] != 0:
detected = True
else:
detected = False
except:
detected = False
return detected
def turn_where(mask):
roi = mask[100:190, :]
cv2.imshow('turn where', roi)
lines = detect_lines(roi)
lines = lines.reshape(-1,2,2)
slope = (lines[:,1,1]-lines[:,0,1]) / (lines[:,1,0]-lines[:,0,0])
mean_pix = np.mean(lines[np.where(abs(slope)<0.2)][:,:,0])
return mean_pix
def detect_side(side_mask):
side_pix = np.mean(np.where(side_mask[150:190, :]>0), axis=1)[1]
return side_pix
def detect_sign(frame, hsv_frame):
types = ['left', 'straight', 'right']
mask = cv2.inRange(hsv_frame, np.array([100,160,90]), np.array([160,220,220]))
mask[:30,:]=0
try:
points, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
sorted_points = sorted(points, key=len)
if cv2.contourArea(sorted_points[-1])>30:
x,y,w,h = cv2.boundingRect(sorted_points[-1])
if (x>5) and (x+w<251) and (y>5) and (y+h<251):
sign = frame[y:y+h,x:x+w]
sign = cv2.resize(sign, (25,25))/255
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2)
return types[np.argmax(sign_model.predict(sign.reshape(1,25,25,3)))]
else:
return 'nothing'
else:
return 'nothing'
except:
return 'nothing'
def red_sign_state(red_mask):
points, _ = cv2.findContours(red_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
sorted_points = sorted(points, key=len)
try:
red_area = cv2.contourArea(sorted_points[-1])
if red_area > 50:
print('red sign detected!')
return True
else:
return False
except:
return False
def stop_the_car(car):
car.setSteering(0)
while car.getSpeed():
car.setSpeed(-100)
car.getData()
car.setSpeed(0)
return True
def turn_the_car(car,s,t):
time1 = time.time()
while((time.time()-time1)<t):
car.getData()
car.setSteering(s)
car.setSpeed(15)
def go_back(car, t):
time1 = time.time()
while((time.time()-time1)<t):
car.getData()
car.setSpeed(-15)
car.setSpeed(0)
`

Stereo camera structured light disparity problem

i want to build 3d scanner with stereo camera and LED Projector. I calibrated the stereo camera and created the mechanical system. I project gray code and capture them with two camera. I decoded the images and take correspondence image. But i can't triangulate the decoded points. This is my reference project for generate pattern and decode them.
Reference Github project
And this is my code
import numpy as np
import cv2
import structuredlight as sl
def generate_rectify_data(calib_data, size):
XML_File = cv2.FileStorage(calib_data, cv2.FILE_STORAGE_READ)
M1 = XML_File.getNode('Camera_Matrix_Left').mat()
M2 = XML_File.getNode('Camera_Matrix_Right').mat()
d1 = XML_File.getNode('Camera_Distortion_Left').mat()
d2 = XML_File.getNode('Camera_Distortion_Right').mat()
R = XML_File.getNode('Rotation_Matrix').mat()
t = XML_File.getNode('Translation_Matrix').mat()
flag = cv2.CALIB_ZERO_DISPARITY
R1, R2, P1, P2, Q = cv2.stereoRectify(cameraMatrix1=M1, cameraMatrix2=M2,
distCoeffs1=d1, distCoeffs2=d2, R=R, T=t, flags=flag, alpha=-1, imageSize=size,
newImageSize=size)[0:5]
map_x_l, map_y_l = cv2.initUndistortRectifyMap(M1, d1, R1, P1, size, cv2.CV_32FC1)
map_x_r, map_y_r = cv2.initUndistortRectifyMap(M2, d2, R2, P2, size, cv2.CV_32FC1)
return map_x_l, map_y_l, map_x_r, map_y_r, P1, P2,Q
def rectify(img, map_x, map_y):
res = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR, cv2.BORDER_CONSTANT)
return res
"""
***I generate pattern like this and capture them in another python script***
W = 240
H = 240
gray = sl.Gray()
imlist_posi_x_pat = gray.generate((W, H))
imlist_posi_y_pat = sl.transpose(gray.generate((H, W)))
"""
if __name__ == '__main__':
img_size = (1648, 1232)
map_x_l, map_y_l, map_x_r, map_y_r, P1, P2, Q = generate_rectify_data(
"C:/Users/XXX/PycharmProjects/Stereo_Structured_Light/Calibration_Data"
"/Calibration_Parameters_1.xml", size=(1648, 1232))
rect_list_l, rect_list_r = [], []
imlist_posi_x_cap_R = []
imlist_posi_y_cap_R = []
imlist_posi_x_cap_L = []
imlist_posi_y_cap_L = []
for i in range(0,16):
img_l = cv2.imread("C:/OxO_Scan/Images_1/Left_cam3/L_" + str(i) + ".png", 0)
img_r = cv2.imread("C:/OxO_Scan/Images_1/Right_cam3/R_" + str(i) + ".png", 0)
l_rect = rectify(img_l, map_x_l, map_y_l)
r_rect = rectify(img_r, map_x_r, map_y_r)
if i < 8: # 8 for the horizontal, 8 for the vertical pattern images
imlist_posi_x_cap_R.append(r_rect)
imlist_posi_x_cap_L.append(l_rect)
else:
imlist_posi_y_cap_R.append(r_rect)
imlist_posi_y_cap_L.append(l_rect)
W = 240
H = 240
gray = sl.Gray()
img_index_x_R = gray.decode(imlist_posi_x_cap_R, thresh=40)
img_index_x_L = gray.decode(imlist_posi_x_cap_L, thresh=40)
img_index_y_R = gray.decode(imlist_posi_y_cap_R, thresh=40)
img_index_y_L = gray.decode(imlist_posi_y_cap_L, thresh=40)
img_correspondence_x_r = cv2.merge([0.0 * np.zeros_like(img_index_x_R),
img_index_x_R / W, img_index_y_R / H])
img_correspondence_r = np.clip(img_correspondence_x_r * 255.0, 0,
255).astype(np.uint8)
img_correspondence_y_l = cv2.merge([0.0 * np.zeros_like(img_index_x_L),
img_index_x_L / W, img_index_y_L / H])
img_correspondence_l = np.clip(img_correspondence_y_l * 255.0, 0,
255).astype(np.uint8)
####################################
cv2.imshow("a", cv2.resize(img_correspondence_l, (640, 480)))
cv2.imshow("b", cv2.resize(img_correspondence_r, (640, 480)))
cv2.waitKey()
cv2.destroyAllWindows()
img_correspondence_L_2 = np.copy(img_correspondence_l)
img_correspondence_R_2 = np.copy(img_correspondence_r)
cam_pts_l, cam_pts_r = [], []
cam_pts_l2, cam_pts_r2 = [], []
for i in range(img_correspondence_l.shape[0]):
for j in range(img_correspondence_l.shape[1]):
if (img_correspondence_l[i][j] != 0).any():
qwert = img_index_x_L[i][j]
cam_pts_l.append([j, i])
cam_pts_r.append([j+qwert, i])
cam_pts_l = np.array(cam_pts_l, dtype=np.float32)
cam_pts_r = np.array(cam_pts_r, dtype=np.float32)
cam_pts_l = np.array(cam_pts_l)[:, np.newaxis, :]
cam_pts_r = np.array(cam_pts_r)[:, np.newaxis, :]
pts4D = cv2.triangulatePoints(P1, P2, np.float32(cam_pts_l),np.float32(cam_pts_r)).T
pts3D = (pts4D[:, :3] / pts4D[:, -1:])
I don't know what to do in code for loop "for i in range(img_correspondence_l.shape[0]):" For example, I cannot find where a point that I found using left correspondence image in the left camera image corresponds to in the right camera image. j+img_index_x_L[i][j] does not give correct results. What should i do here
Thanks for your answers

how to resolve this error which generates in matching two images in image stitching code

while doing image stitching code in google colab I got an error can anyone help how to resolve it?
ERROR: File "<ipython-input-12-7c271414318b>", line 58
def filter_matches(self, matches, ratio = 0.75):
^
IndentationError: unindent does not match any outer indentation level
CODE:
import os
import sys
import cv2
import math
import numpy as np
import utils
from numpy import linalg
class AlignImagesRansac(object):
def _init_(self, image_dir, key_frame, output_dir, img_filter=None):
'''
image_dir: 'C:\Users\Hamza Ahmed\Desktop\auto' containing all images
key_frame: 'C:\Users\Hamza Ahmed\Desktop\auto\c.jpg' of the base image
output_dir: 'C:\Users\Hamza Ahmed\Desktop\auto' where to save output images
optional:
img_filter = 'JPG'; None->Take all images
'''
self.key_frame_file = os.path.split(key_frame)[-1]
self.output_dir = output_dir
# Open the directory given in the arguments
self.dir_list = []
try:
self.dir_list = os.listdir(image_dir)
if img_filter:
# remove all files that doen't end with .[image_filter]
self.dir_list = filter(lambda x: x.find(img_filter) > -1, self.dir_list)
try: #remove Thumbs.db, is existent (windows only)
self.dir_list.remove('Thumbs.db')
except ValueError:
pass
except:
print >> sys.stderr, ("Unable to open directory: %s" % image_dir)
sys.exit(-1)
self.dir_list = map(lambda x: os.path.join(image_dir, x), self.dir_list)
self.dir_list = filter(lambda x: x != key_frame, self.dir_list)
base_img_rgb = cv2.imread(key_frame)
if base_img_rgb == None:
raise IOError("%s doesn't exist" %key_frame)
# utils.showImage(base_img_rgb, scale=(0.2, 0.2), timeout=0)
# cv2.destroyAllWindows()
final_img = self.stitchImages(base_img_rgb, 0)
def filter_matches(self, matches, ratio = 0.75):
filtered_matches = []
for m in matches:
if len(m) == 2 and m[0].distance < m[1].distance * ratio:
filtered_matches.append(m[0])
return filtered_matches
def imageDistance(self, matches):
sumDistance = 0.0
for match in matches:
sumDistance += match.distance
return sumDistance
def findDimensions(self, image, homography):
base_p1 = np.ones(3, np.float32)
base_p2 = np.ones(3, np.float32)
base_p3 = np.ones(3, np.float32)
base_p4 = np.ones(3, np.float32)
(y, x) = image.shape[:2]
base_p1[:2] = [0,0]
base_p2[:2] = [x,0]
base_p3[:2] = [0,y]
base_p4[:2] = [x,y]
max_x = None
max_y = None
min_x = None
min_y = None
for pt in [base_p1, base_p2, base_p3, base_p4]:
hp = np.matrix(homography, np.float32) * np.matrix(pt, np.float32).T
hp_arr = np.array(hp, np.float32)
normal_pt = np.array([hp_arr[0]/hp_arr[2], hp_arr[1]/hp_arr[2]], np.float32)
if ( max_x == None or normal_pt[0,0] > max_x ):
max_x = normal_pt[0,0]
if ( max_y == None or normal_pt[1,0] > max_y ):
max_y = normal_pt[1,0]
if ( min_x == None or normal_pt[0,0] < min_x ):
min_x = normal_pt[0,0]
if ( min_y == None or normal_pt[1,0] < min_y ):
min_y = normal_pt[1,0]
min_x = min(0, min_x)
min_y = min(0, min_y)
return (min_x, min_y, max_x, max_y)
def stitchImages(self, base_img_rgb, round=0):
if ( len(self.dir_list) < 1 ):
return base_img_rgb
# print base_img_rgb.channels()
# if(image.channels()==1)
# { /* Grayscale */ }
# else if (image.channels==4)
# { /* ARGB or RGBA image */
base_img = cv2.GaussianBlur(cv2.cvtColor(base_img_rgb,cv2.COLOR_BGR2GRAY), (5,5), 0)
# Use the SIFT feature detector
detector = cv2.SIFT()
# Find key points in base image for motion estimation
base_features, base_descs = detector.detectAndCompute(base_img, None)
# Create new key point list
# key_points = []
# for kp in base_features:
# key_points.append((int(kp.pt[0]),int(kp.pt[1])))
# utils.showImage(base_img, key_points, scale=(0.2, 0.2), timeout=0)
# cv2.destroyAllWindows()
# Parameters for nearest-neighbor matching
FLANN_INDEX_KDTREE = 1 # bug: flann enums are missing
flann_params = dict(algorithm = FLANN_INDEX_KDTREE,
trees = 5)
matcher = cv2.FlannBasedMatcher(flann_params, {})
print ("Iterating through next images...")
closestImage = None
# TODO: Thread this loop since each iteration is independent
# Find the best next image from the remaining images
for next_img_path in self.dir_list:
print ("Reading %s..." % next_img_path)
if ( self.key_frame_file in next_img_path ):
print ("\t Skipping %s..." % self.key_frame_file)
continue
# Read in the next image...
next_img_rgb = cv2.imread(next_img_path)
next_img = cv2.GaussianBlur(cv2.cvtColor(next_img_rgb,cv2.COLOR_BGR2GRAY), (5,5), 0)
# if ( next_img.shape != base_img.shape ):
# print "\t Skipping %s, bad shape: %s" % (next_img_path, next_img.shape)
# continue
print ("\t Finding points...")
# Find points in the next frame
next_features, next_descs = detector.detectAndCompute(next_img, None)
matches = matcher.knnMatch(next_descs, trainDescriptors=base_descs, k=2)
print ("\t Match Count: ", len(matches))
matches_subset = self.filter_matches(matches)
print ("\t Filtered Match Count: ", len(matches_subset))
distance = self.imageDistance(matches_subset)
print ("\t Distance from Key Image: ", distance)
averagePointDistance = distance/float(len(matches_subset))
print ("\t Average Distance: ", averagePointDistance)
kp1 = []
kp2 = []
for match in matches_subset:
kp1.append(base_features[match.trainIdx])
kp2.append(next_features[match.queryIdx])
p1 = np.array([k.pt for k in kp1])
p2 = np.array([k.pt for k in kp2])
H, status = cv2.findHomography(p1, p2, cv2.RANSAC, 5.0)
print ('%d / %d inliers/matched' % (np.sum(status), len(status)))
inlierRatio = float(np.sum(status)) / float(len(status))
# if ( closestImage == None or averagePointDistance < closestImage['dist'] ):
if ( closestImage == None or inlierRatio > closestImage['inliers'] ):
closestImage = {}
closestImage['h'] = H
closestImage['inliers'] = inlierRatio
closestImage['dist'] = averagePointDistance
closestImage['path'] = next_img_path
closestImage['rgb'] = next_img_rgb
closestImage['img'] = next_img
closestImage['feat'] = next_features
closestImage['desc'] = next_descs
closestImage['match'] = matches_subset
print ("Closest Image: ", closestImage['path'])
print ("Closest Image Ratio: ", closestImage['inliers'])
self.dir_list = filter(lambda x: x != closestImage['path'], self.dir_list)
# utils.showImage(closestImage['img'], scale=(0.2, 0.2), timeout=0)
# cv2.destroyAllWindows()
H = closestImage['h']
H = H / H[2,2]
H_inv = linalg.inv(H)
if ( closestImage['inliers'] > 0.1 ): # and
(min_x, min_y, max_x, max_y) = self.findDimensions(closestImage['img'], H_inv)
# Adjust max_x and max_y by base img size
max_x = max(max_x, base_img.shape[1])
max_y = max(max_y, base_img.shape[0])
move_h = np.matrix(np.identity(3), np.float32)
if ( min_x < 0 ):
move_h[0,2] += -min_x
max_x += -min_x
if ( min_y < 0 ):
move_h[1,2] += -min_y
max_y += -min_y
print ("Homography: \n", H)
print ("Inverse Homography: \n", H_inv)
print ("Min Points: ", (min_x, min_y))
mod_inv_h = move_h * H_inv
img_w = int(math.ceil(max_x))
img_h = int(math.ceil(max_y))
print ("New Dimensions: ", (img_w, img_h))
# Warp the new image given the homography from the old image
base_img_warp = cv2.warpPerspective(base_img_rgb, move_h, (img_w, img_h))
print ("Warped base image")
# utils.showImage(base_img_warp, scale=(0.2, 0.2), timeout=5000)
# cv2.destroyAllWindows()
next_img_warp = cv2.warpPerspective(closestImage['rgb'], mod_inv_h, (img_w, img_h))
print ("Warped next image")
# utils.showImage(next_img_warp, scale=(0.2, 0.2), timeout=5000)
# cv2.destroyAllWindows()
# Put the base image on an enlarged palette
enlarged_base_img = np.zeros((img_h, img_w, 3), np.uint8)
print ("Enlarged Image Shape: ", enlarged_base_img.shape)
print ("Base Image Shape: ", base_img_rgb.shape)
print ("Base Image Warp Shape: ", base_img_warp.shape)
# enlarged_base_img[y:y+base_img_rgb.shape[0],x:x+base_img_rgb.shape[1]] = base_img_rgb
# enlarged_base_img[:base_img_warp.shape[0],:base_img_warp.shape[1]] = base_img_warp
# Create a mask from the warped image for constructing masked composite
(ret,data_map) = cv2.threshold(cv2.cvtColor(next_img_warp, cv2.COLOR_BGR2GRAY),
0, 255, cv2.THRESH_BINARY)
enlarged_base_img = cv2.add(enlarged_base_img, base_img_warp,
mask=np.bitwise_not(data_map),
dtype=cv2.CV_8U)
# Now add the warped image
final_img = cv2.add(enlarged_base_img, next_img_warp,
dtype=cv2.CV_8U)
# utils.showImage(final_img, scale=(0.2, 0.2), timeout=0)
# cv2.destroyAllWindows()
# Crop off the black edges
final_gray = cv2.cvtColor(final_img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(final_gray, 1, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
print ("Found %d contours..." % (len(contours)))
max_area = 0
best_rect = (0,0,0,0)
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
# print "Bounding Rectangle: ", (x,y,w,h)
deltaHeight = h-y
deltaWidth = w-x
area = deltaHeight * deltaWidth
if ( area > max_area and deltaHeight > 0 and deltaWidth > 0):
max_area = area
best_rect = (x,y,w,h)
if ( max_area > 0 ):
print ("Maximum Contour: ", max_area)
print ("Best Rectangle: ", best_rect)
final_img_crop = final_img[best_rect[1]:best_rect[1]+best_rect[3],
best_rect[0]:best_rect[0]+best_rect[2]]
# utils.showImage(final_img_crop, scale=(0.2, 0.2), timeout=0)
# cv2.destroyAllWindows()
final_img = final_img_crop
# Write out the current round
final_filename = "%s/%d.JPG" % (self.output_dir, round)
cv2.imwrite(final_filename, final_img)
return self.stitchImages(final_img, round+1)
else:
return self.stitchImages(base_img_rgb, round+1)
# ----------------------------------------------------------------------------
#if _name_ == '_main_':
# if ( len(args) < 4 ):
# print >> sys.stderr, ("Usage: %s <image_dir> <key_frame> <output>" % args[0])
# sys.exit(-1)
#AlignImagesRansac(sys.args[1:])

Captcha crashes when selected. selenium Python

I am trying to download images using this code. However, The website comes up with a captcha. When I try to select the captcha it displays a broken PC image. Cannot figure a way past this. Is their a way to avoid the captcha altogether? Or select it somehow for clicking options via selenium. It's a long code but an MRE.
from selenium import webdriver
from bs4 import BeautifulSoup as soup
from datetime import date ,timedelta
import requests
import time
import base64
import cv2
import pytesseract
import xlsxwriter
import numpy as np
import pandas as pd
import os
import shutil
driver = webdriver.Chrome("chromedriver")
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
excel_name = ['Сите','Упис на основање','2б Ново со спојување на __','3б Ново со раздвојување од __','5б Ново со издвојување од__','Упис на промена','Документ за корекција','1б Присоединување во __','4б Превземање со раздвојување на __','5а Издвојување во ново__','6б Превземање од__','6а Издвојување во __','Документ за регистрирање на работно време','Документ за определување на главна приходна шифра и големина','Документ за евидентирање на казна/санкција','Документ за евидентирање на бришење на казна/санкција','Документ за евидентирање на стечај на друг субјект','Документ за евидентирање на заклучување на стечај на друг субјект','Упис на бришење','2а Спојување во ново__со бришење','4а Раздвојување со превземање во __ со бришење','3а Раздвојување на ново __ со бришење','1а Присоединување на __ со бришење','Судска Процедура - Стечај','Ликвидација','Претстечај (Претходна постапка)','Објава(Друго)','Објава(Стечајна постапка)','Објава(Ликвидациона постапка)','Вонсудска спогодба','Објава(Вонсудска спогодба)','Предбелешка']
#excel_name = ['Сите','Упис на основање','2б Ново со спојување на __','Упис на промена']
image_name = ['image', 'image0', 'image1', 'image2', 'image3', 'image4', 'image5', 'image6', 'image7', 'image8', 'image9', 'image10', 'image11', 'image12', 'image13', 'image14', 'image15', 'image16', 'image17', 'image18', 'image19', 'image20', 'image21', 'image22', 'image23', 'image24', 'image25', 'image26', 'image27', 'image28', 'image29', 'image30']
def get_text(data_number, image_name, excel_name):
workbook = xlsxwriter.Workbook(str(date.today() - timedelta(days=1)) + '-' + excel_name + '.xlsx')
worksheet = workbook.add_worksheet("content")
row = 0
print(image_name, data_number)
# Load image, grayscale, and Otsu's threshold
for i in range(data_number):
print('./images/' + str(date.today() - timedelta(days=3)) + '-' + image_name + str(i) + '.png')
image = cv2.imread('./images/' + str(date.today() - timedelta(days=3)) + '-' + image_name + str(i) + '.png')
try:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
except:
continue
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(thresh, [c], -1, (0, 0, 0), 2)
# Remove vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 15))
detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(thresh, [c], -1, (0, 0, 0), 3)
# Dilate to connect text and remove dots
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 1))
dilate = cv2.dilate(thresh, kernel, iterations=2)
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 500:
cv2.drawContours(dilate, [c], -1, (0, 0, 0), -1)
# Bitwise-and to reconstruct image
result = cv2.bitwise_and(image, image, mask=dilate)
result[dilate == 0] = (255, 255, 255)
# OCR
data = pytesseract.image_to_string(result, lang='mkd+eng', config='--psm 6')
# data = pytesseract.image_to_string(result,config='--psm 6')
#print(data)
worksheet.write(row, 0, data)
row = row + 1
workbook.close()
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
def get_table(path):
image = cv2.imread(path, 0)
image_colour=cv2.imread(path)
ret, img = cv2.threshold(image, 240, 255, cv2.THRESH_BINARY)
img_inv = 255 - img
kernel_len = np.array(img).shape[1] // 100
# Defining a vertical kernel to detect all vertical lines of image
ver_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_len))
img_bin = img_inv
image_1 = cv2.erode(img_bin, ver_kernel, iterations=3)
vertical_lines = cv2.dilate(image_1, ver_kernel, iterations=3)
cv2.imwrite("vertical.jpg", vertical_lines)
hor_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_len, 1))
# A kernel of 2x2
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
image_2 = cv2.erode(img_bin, hor_kernel, iterations=3)
horizontal_lines = cv2.dilate(image_2, hor_kernel, iterations=3)
cv2.imwrite("horizontal.jpg", horizontal_lines)
img_vh = cv2.addWeighted(vertical_lines, 0.5, horizontal_lines, 0.5, 0.0)
# Eroding and thesholding the image
img_vh = cv2.erode(~img_vh, kernel, iterations=2)
thresh, img_vh = cv2.threshold(img_vh, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imwrite("img_vh.jpg", img_vh)
#bitxor = cv2.bitwise_xor(img, img_vh)
#bitnot = cv2.bitwise_not(bitxor)
contours, hierarchy = cv2.findContours(img_vh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Sort all the contours by top to bottom.
contours, boundingBoxes = sort_contours(contours, method="top-to-bottom")
# Creating a list of heights for all detected boxes
heights = [boundingBoxes[i][3] for i in range(len(boundingBoxes))]
# Get mean of heights
mean = np.mean(heights)
box = []
# Get position (x,y), width and height for every contour and show the contour on image
for c in contours:
x, y, w, h = cv2.boundingRect(c)
if (100 <w < 0.8*image.shape[1] and 40 < h < 500):
image = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
box.append([x, y, w, h])
return arrange_rows(box,mean),image_colour
def arrange_rows(box,mean):
row = []
column = []
j = 0
# Sorting the boxes to their respective row and column
for i in range(len(box)):
if (i == 0):
column.append(box[i])
previous = box[i]
else:
if (box[i][1] <= previous[1] + mean / 2):
column.append(box[i])
previous = box[i]
if (i == len(box) - 1):
row.append(column)
else:
row.append(column)
column = []
previous = box[i]
column.append(box[i])
return row
def cell_ocr(im,rcts):
rcts = [sorted(c, key=lambda x: x[0]) for c in rcts]
output = []
for i, row in enumerate(rcts):
y, x, w, h = row[0]
y1, x1, w1, h1 = row[1]
finalimg = im[x:x + h, y:y + w]
finalimg_val = im[x1:x1 + h1, y1:y1 + w1]
resizing = cv2.resize(finalimg, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
resizing_val = cv2.resize(finalimg_val, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
out = pytesseract.image_to_string(resizing, lang='mkd+eng')
out_val = pytesseract.image_to_string(resizing_val, lang='mkd+eng')
output.append([out.strip(), out_val.strip()])
return output
def get_text_v(path="images", date_of=(date.today() - timedelta(days=1))):
type_dict = {}
for f in os.listdir(path):
print("Processing File : " + str(f) + " ...")
r, im = get_table(os.path.join(path,f))
output=cell_ocr(im,r)
try:
idx=[x[0] for x in output].index("Вид на упис")
attr_key = output[idx][1]
except ValueError:
attr_key = "custom"
if attr_key in type_dict:
grp_df=pd.DataFrame(output).groupby(0,as_index=False).agg(lambda x: ",".join([str(xc) for xc in x]))
type_dict[attr_key]=type_dict[attr_key].merge(grp_df, how="outer",on=0)
else:
type_dict[attr_key]=pd.DataFrame(output).groupby(0,as_index=False).agg(lambda x: ",".join([str(xc) for xc in x]))
type_dict.pop('Упис на промена', None) # this should delete the Упис на промена sheet
type_dict.pop('Упис на основање', None) # this should delete the Упис на основање sheet
type_dict.pop('Упис на основање', None) # this should delete the Упис на основање sheet
with pd.ExcelWriter("workbook"+str(date_of)+'.xlsx') as writer:
for k, v in type_dict.items():
v.transpose().to_excel(writer, sheet_name=k[:30], header=False, index=False)
return type_dict
def main():
count = 0
driver.get("http://crm.com.mk/mk/otvoreni-podatotsi/objavi-na-upisi-za-subjekti")
time.sleep(30)
for l in range(len(excel_name)):
print("visiting option : " + excel_name[l])
data_list = []
if (l < 1):
continue
today = str(date.today() - timedelta(days=3)).split('-')
get_date = today[2] + '.' + today[1] + '.' + today[0]
driver.find_element_by_xpath(
'//*[#id="content"]/cms-container/crm-template-fs-latestannouncement/crm-cnt-latestannouncement/crm-cnt-latestannouncement-list/div/crm-cnt-latestannouncement-list-oss/div[2]/div/div[1]/div[2]/div[1]/fieldset/span/select/option[' + str(
l + 1) + ']').click()
time.sleep(2)
driver.find_element_by_xpath(
'//*[#id="content"]/cms-container/crm-template-fs-latestannouncement/crm-cnt-latestannouncement/crm-cnt-latestannouncement-list/div/crm-cnt-latestannouncement-list-oss/div[2]/div/div[1]/div[2]/div[2]/fieldset/input').send_keys(
get_date)
time.sleep(2)
driver.find_element_by_xpath(
'//*[#id="content"]/cms-container/crm-template-fs-latestannouncement/crm-cnt-latestannouncement/crm-cnt-latestannouncement-list/div/crm-cnt-latestannouncement-list-oss/div[2]/div/div[2]/div/button[1]').click()
time.sleep(10)
page_content = soup(driver.page_source, 'html.parser')
if (page_content.find('table', {'class': 'table--mobile'}) != None):
if (page_content.find('ul', {'class': 'ngx-pagination'}) != None):
page_list = page_content.find('ul', {'class': 'ngx-pagination'}).findAll("li")
print(page_list[len(page_list) - 2].text.replace('page ', ''))
for i in range(int(page_list[len(page_list) - 2].text.replace('page ', ''))):
time.sleep(3)
driver.find_element_by_xpath(
'//*[#id="content"]/cms-container/crm-template-fs-latestannouncement/crm-cnt-latestannouncement/crm-cnt-latestannouncement-list/div/crm-cnt-latestannouncement-list-oss/div[4]/div/div/pagination-controls/pagination-template/ul/li[' + str(
i + 3) + ']').click()
time.sleep(3)
page_res = soup(driver.page_source, 'html.parser')
if (page_res.find('table', {'class': 'table--mobile'}) != None):
table_list = page_res.find('table', {'class': 'table--mobile'}).findAll('tr')
for j in range(len(table_list)):
if (j > 0):
tr_list = table_list[j].findAll('td')
data_list.append(tr_list[0].text)
else:
count = 1
if count == 1:
break
else:
table_list = page_content.find('table', {'class': 'table--mobile'}).findAll('tr')
for j in range(len(table_list)):
if (j > 0):
tr_list = table_list[j].findAll('td')
data_list.append(tr_list[0].text)
print("number of items found in option " + excel_name[l] + " : " + str(len(data_list)))
data_number = len(data_list)
if (data_number == 0):
driver.find_element_by_xpath(
'//*[#id="content"]/cms-container/crm-template-fs-latestannouncement/crm-cnt-latestannouncement/crm-cnt-latestannouncement-list/div/crm-cnt-latestannouncement-list-oss/div[2]/div/div[1]/div[2]/div[2]/fieldset/input').clear()
continue
for k in range(len(data_list)):
print("Downloading image number : " + str(k) + "/" + str(len(data_list)))
#if(k>2):
# break
driver.get("http://crm.com.mk/mk/otvoreni-podatotsi/objavi-na-upisi-za-subjekti?id=" + data_list[k] + "&p=1")
time.sleep(60)
page_cont = soup(driver.page_source, 'html.parser')
if (page_cont.find('div', {'class': 'row center'}) != None):
image_src = page_cont.find('div', {'class': 'row center'}).div.img['src']
try:
imagedata = base64.b64decode(image_src.replace('data:image/png;base64,', ''))
image = open("./images/" + str(date.today() - timedelta(days=)) + '-' + image_name[l] + str(k) + ".png", "wb")
image.write(imagedata)
image.close()
except:
print("An exception occurred on image " + str(k) +" with id : " + str(data_list[k]) )
driver.get("http://crm.com.mk/mk/otvoreni-podatotsi/objavi-na-upisi-za-subjekti")
time.sleep(20)
if excel_name[l]=="Упис на промена":
get_text(data_number, image_name[l], excel_name[l])
if excel_name[l]=="Упис на основање":
get_text(data_number, image_name[l], excel_name[l])
count = 0
driver.close()
main()
print("Generating workbook please wait ...")
get_text_v()
print("Workbook file generated !!")
print("Moving files from images to oldimages ...")
source_dir = 'images'
target_dir = 'oldimages'
file_names = os.listdir(source_dir)
for file_name in file_names:
print("moving file " + str(file_name) + " ...")
try:
shutil.move(os.path.join(source_dir, file_name), target_dir)
except:
print("An exception occurred, File already exist !!!")
print("Moving files from images to oldimages Done !!!")

Crop Row Detection script

I want to detect crop rows using aerial images(CRBD). I have done the necessary image processing like converting to grayscale, edge detection, skeletonization, Hough Transform(to identify and draw the lines), and I also set the accumulator angle to math.pi*4.0/180, which I varied time after time.
The algorithm works well at detection approximately 4 crop lines, I want to improve it so that it can detect variable number of crop rows, and it should be able to highlight this crop rows
Here is a link to the sample code I modified Here
import os
import os.path
import time
import cv2
import numpy as np
import math
### Setup ###
image_data_path = os.path.abspath('../8470p/CRBD/Images')
gt_data_path = os.path.abspath('../8470p/GT data')
image_out_path = os.path.abspath('../8470p/algorithm_1')
use_camera = False # whether or not to use the test images or camera
images_to_save = [2, 3, 4, 5] # which test images to save
timing = False # whether to time the test images
curr_image = 0 # global counter
HOUGH_RHO = 2 # Distance resolution of the accumulator in pixels
HOUGH_ANGLE = math.pi*4.0/18 # Angle resolution of the accumulator in radians
HOUGH_THRESH_MAX = 80 # Accumulator threshold parameter. Only those lines are
returned that get votes
HOUGH_THRESH_MIN = 10
HOUGH_THRESH_INCR = 1
NUMBER_OF_ROWS = 10 # how many crop rows to detect
THETA_SIM_THRESH = math.pi*(6.0/180) # How similar two rows can be
RHO_SIM_THRESH = 8 # How similar two rows can be
ANGLE_THRESH = math.pi*(30.0/180) # How steep angles the crop rows can be in
radians
def grayscale_transform(image_in):
'''Converts RGB to Grayscale and enhances green values'''
b, g, r = cv2.split(image_in)
return 2*g - r - b
def save_image(image_name, image_data):
'''Saves image if user requests before runtime'''
if curr_image in images_to_save:
image_name_new = os.path.join(image_out_path, "
{0}_{1}.jpg".format(image_name,
str(curr_image) ))
def skeletonize(image_in):
'''Inputs and grayscale image and outputs a binary skeleton image'''
size = np.size(image_in)
skel = np.zeros(image_in.shape, np.uint8)
ret, image_edit = cv2.threshold(image_in, 0, 255, cv2.THRESH_BINARY |
cv2.THRESH_OTSU)
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
done = False
while not done:
eroded = cv2.erode(image_edit, element)
temp = cv2.dilate(eroded, element)
temp = cv2.subtract(image_edit, temp)
skel = cv2.bitwise_or(skel, temp)
image_edit = eroded.copy()
zeros = size - cv2.countNonZero(image_edit)
if zeros == size:
done = True
return skel
def tuple_list_round(tuple_list, ndigits_1=0, ndigits_2=0):
'''Rounds each value in a list of tuples to the number of digits
specified
'''
new_list = []
for (value_1, value_2) in tuple_list:
new_list.append( (round(value_1, ndigits_1), round(value_2,
ndigits_2)) )
return new_list
def crop_point_hough(crop_points):
'''Iterates though Hough thresholds until optimal value found for
the desired number of crop rows. Also does filtering.
'''
height = len(crop_points)
width = len(crop_points[0])
hough_thresh = HOUGH_THRESH_MAX
rows_found = False
while hough_thresh > HOUGH_THRESH_MIN and not rows_found:
crop_line_data = cv2.HoughLines(crop_points, HOUGH_RHO, HOUGH_ANGLE,
hough_thresh)
crop_lines = np.zeros((height, width, 3), dtype=np.uint8)
crop_lines_hough = np.zeros((height, width, 3), dtype=np.uint8)
if crop_line_data is not None:
# get rid of duplicate lines. May become redundant if a similarity
threshold is done
crop_line_data_1 = tuple_list_round(crop_line_data[:,0,:],-1, 4)
crop_line_data_2 = []
x_offsets = []
crop_lines_hough = np.zeros((height, width, 3), dtype=np.uint8)
for (rho, theta) in crop_line_data_1:
a = math.cos(theta)
b = math.sin(theta)
x0 = a*rho
y0 = b*rho
point1 = (int(round(x0+1000*(-b))), int(round(y0+1000*(a))))
point2 = (int(round(x0-1000*(-b))), int(round(y0-1000*(a))))
cv2.line(crop_lines_hough, point1, point2, (0, 0, 255), 2)
for curr_index in range(len(crop_line_data_1)):
(rho, theta) = crop_line_data_1[curr_index]
is_faulty = False
if ((theta >= ANGLE_THRESH) and (theta <= math.pi-
ANGLE_THRESH)) or(theta <= 0.001):
is_faulty = True
else:
for (other_rho, other_theta) in
crop_line_data_1[curr_index+1:]:
if abs(theta - other_theta) < THETA_SIM_THRESH:
is_faulty = True
elif abs(rho - other_rho) < RHO_SIM_THRESH:
is_faulty = True
if not is_faulty:
crop_line_data_2.append( (rho, theta) )
for (rho, theta) in crop_line_data_2:
a = math.cos(theta)
b = math.sin(theta)
c = math.tan(theta)
x0 = a*rho
y0 = b*rho
point1 = (int(round(x0+1000*(-b))), int(round(y0+1000*(a))))
point2 = (int(round(x0-1000*(-b))), int(round(y0-1000*(a))))
cv2.line(crop_lines, point1, point2, (0, 0, 255), 2)
#cv2.circle(crop_lines, (np.clip(int(round(a*rho+c*
#(0.5*height))),0 ,239), 0), 4, (255,0,0), -1)
#cv2.circle(crop_lines, (np.clip(int(round(a*rho-c*
#(0.5*height))),0 ,239), height), 4, (255,0,0), -1)
cv2.circle(crop_lines, (np.clip(int(round(rho/a)),0 ,239), 0), 5,
(255,0,0), -1)
#cv2.circle(img,(447,63), 63, (0,0,255), -1)
x_offsets.append(np.clip(int(round(rho/a)),0 ,239))
cv2.line(crop_lines, point1, point2, (0, 0, 255), 2)
if len(crop_line_data_2) >= NUMBER_OF_ROWS:
rows_found = True
hough_thresh -= HOUGH_THRESH_INCR
if rows_found == False:
print(NUMBER_OF_ROWS, "rows_not_found")
x_offset = min (x_offsets)
width = max (x_offsets) - min (x_offsets)
return (crop_lines, crop_lines_hough, x_offset, width)
def crop_row_detect(image_in):
'''Inputs an image and outputs the lines'''
save_image('0_image_in', image_in)
### Grayscale Transform ###
image_edit = grayscale_transform(image_in)
save_image('1_image_gray', image_edit)
### Skeletonization ###
skeleton = skeletonize(image_edit)
save_image('2_image_skeleton', skeleton)
### Hough Transform ###
(crop_lines, crop_lines_hough, x_offset, width) =
crop_point_hough(skeleton)
save_image('3_image_hough',cv2.addWeighted(image_in, 1,
crop_lines_hough, 1, 0.0))
save_image('4_image_lines',cv2.addWeighted(image_in, 1,crop_lines,1,0.0))
return (crop_lines , x_offset, width)
def main():
if use_camera == False:
diff_times = []
for image_name in sorted(os.listdir(image_data_path)):
global curr_image
curr_image += 1
start_time = time.time()
image_path = os.path.join(image_data_path, image_name)
image_in = cv2.imread(image_path)
crop_lines = crop_row_detect(image_in)
if timing == False:
cv2.imshow(image_name, cv2.addWeighted(image_in, 1,
crop_lines, 1, 0.0))
print('Press any key to continue...')
cv2.waitKey()
cv2.destroyAllWindows()
### Timing ###
else:
diff_times.append(time.time() - start_time)
mean = 0
for diff_time in diff_times:
mean += diff_time
### Display Timing ###
print('max time = {0}'.format(max(diff_times)))
print('ave time = {0}'.format(1.0 * mean / len(diff_times)))
cv2.waitKey()
else: # use camera. Hasn't been tested on a farm.
capture = cv2.VideoCapture(0)
while cv2.waitKey(1) < 0:
_, image_in = capture.read()
(crop_lines, x_offset, width) = crop_row_detect(image_in)
cv2.imshow("Webcam", cv2.addWeighted(image_in, 1, crop_lines, 1,
0.0))
capture.release()
cv2.destroyAllWindows()
main()
Input Image
[![Input Image][1]][1]
Output Image
[![][4]][4]
Expected Output
[![Expected Output][5]][5]
I have tried thresholding with cv2.inRange() to find green lines, but am still not getting the desired out.
Also the algorithms seems to be only draw the crop_line_data_2 as shown in the Output Image, it doesn't draw the crop_line_data_1
def threshold_green(image_in):
hsv = cv2.cvtColor(image_in, cv2.COLOR_BGR2HSV)
## mask of green (36,25,25) ~ (86, 255,255)
# mask = cv2.inRange(hsv, (36, 25, 25), (86, 255,255))
mask = cv2.inRange(hsv, (36, 25, 25), (70, 255,255))
## slice the green
imask = mask>0
green = np.zeros_like(image_in, np.uint8)
green[imask] = image_in[imask]
return green

Categories

Resources