intial commit
This commit is contained in:
Binary file not shown.
Executable
+116
@@ -0,0 +1,116 @@
|
||||
# TBD: automatic thresholding, feature map (transformation), PLC library
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import argparse
|
||||
import rospy
|
||||
import time
|
||||
import rospy
|
||||
import cv2
|
||||
import numpy as np
|
||||
import time
|
||||
|
||||
from cv_bridge import CvBridge, CvBridgeError
|
||||
from geometry_msgs.msg import Twist
|
||||
from sensor_msgs.msg import Image
|
||||
|
||||
image_ros = True
|
||||
|
||||
max_value = 255
|
||||
max_value_H = 360//2
|
||||
low_H = 0
|
||||
low_S = 0
|
||||
low_V = 0
|
||||
high_H = max_value_H
|
||||
high_S = max_value
|
||||
high_V = max_value
|
||||
window_capture_name = 'Video Capture'
|
||||
window_detection_name = 'Object Detection'
|
||||
low_H_name = 'Low H'
|
||||
low_S_name = 'Low S'
|
||||
low_V_name = 'Low V'
|
||||
high_H_name = 'High H'
|
||||
high_S_name = 'High S'
|
||||
high_V_name = 'High V'
|
||||
bridge_object = CvBridge()
|
||||
def on_low_H_thresh_trackbar(val):
|
||||
global low_H
|
||||
global high_H
|
||||
low_H = val
|
||||
low_H = min(high_H-1, low_H)
|
||||
cv2.setTrackbarPos(low_H_name, window_detection_name, low_H)
|
||||
def on_high_H_thresh_trackbar(val):
|
||||
global low_H
|
||||
global high_H
|
||||
high_H = val
|
||||
high_H = max(high_H, low_H+1)
|
||||
cv2.setTrackbarPos(high_H_name, window_detection_name, high_H)
|
||||
def on_low_S_thresh_trackbar(val):
|
||||
global low_S
|
||||
global high_S
|
||||
low_S = val
|
||||
low_S = min(high_S-1, low_S)
|
||||
cv2.setTrackbarPos(low_S_name, window_detection_name, low_S)
|
||||
def on_high_S_thresh_trackbar(val):
|
||||
global low_S
|
||||
global high_S
|
||||
high_S = val
|
||||
high_S = max(high_S, low_S+1)
|
||||
cv2.setTrackbarPos(high_S_name, window_detection_name, high_S)
|
||||
def on_low_V_thresh_trackbar(val):
|
||||
global low_V
|
||||
global high_V
|
||||
low_V = val
|
||||
low_V = min(high_V-1, low_V)
|
||||
cv2.setTrackbarPos(low_V_name, window_detection_name, low_V)
|
||||
def on_high_V_thresh_trackbar(val):
|
||||
global low_V
|
||||
global high_V
|
||||
high_V = val
|
||||
high_V = max(high_V, low_V+1)
|
||||
cv2.setTrackbarPos(high_V_name, window_detection_name, high_V)
|
||||
def camera_callback(data):
|
||||
rospy.loginfo("callback started")
|
||||
|
||||
|
||||
try:
|
||||
# Select bgr8 because its the OpenCV encoding by default
|
||||
cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="passthrough")
|
||||
#cv2.imshow("Original_image",cv_image)
|
||||
except CvBridgeError as e:
|
||||
print(e)
|
||||
cv2.waitKey(10)
|
||||
#ret1, cv_image = capture.read()
|
||||
|
||||
frame_HSV = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)
|
||||
frame_threshold = cv2.inRange(frame_HSV, (low_H, low_S, low_V), (high_H, high_S, high_V))
|
||||
|
||||
|
||||
cv2.imshow(window_capture_name, cv_image)
|
||||
cv2.imshow(window_detection_name, frame_threshold)
|
||||
|
||||
if not image_ros:
|
||||
capture = cv2.VideoCapture("/home/andrew/Desktop/webcam_data/webcam/harvest2.mp4")
|
||||
if (capture.isOpened()== False):
|
||||
print("Error opening file.Please check path or name")
|
||||
else:
|
||||
bridge_object = CvBridge()
|
||||
image_sub = rospy.Subscriber("/zed/zed_node/left/image_rect_color",Image,camera_callback) # rectified image from left camerarate = rospy.Rate(10) # 10hz
|
||||
|
||||
|
||||
cv2.namedWindow(window_capture_name)
|
||||
cv2.namedWindow(window_detection_name)
|
||||
cv2.createTrackbar(low_H_name, window_detection_name , low_H, max_value_H, on_low_H_thresh_trackbar)
|
||||
cv2.createTrackbar(high_H_name, window_detection_name , high_H, max_value_H, on_high_H_thresh_trackbar)
|
||||
cv2.createTrackbar(low_S_name, window_detection_name , low_S, max_value, on_low_S_thresh_trackbar)
|
||||
cv2.createTrackbar(high_S_name, window_detection_name , high_S, max_value, on_high_S_thresh_trackbar)
|
||||
cv2.createTrackbar(low_V_name, window_detection_name , low_V, max_value, on_low_V_thresh_trackbar)
|
||||
cv2.createTrackbar(high_V_name, window_detection_name , high_V, max_value, on_high_V_thresh_trackbar)
|
||||
rospy.init_node('hsv_toolbar', anonymous=True)
|
||||
rospy.loginfo("Node is starting ...")
|
||||
|
||||
|
||||
#------------------#
|
||||
while True:
|
||||
time.sleep(0.05)
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import cv2
|
||||
|
||||
camera =cv2.VideoCapture("/dev/video0")
|
||||
|
||||
while True:
|
||||
_,image = camera.read()
|
||||
cv2.imshow("image",image)
|
||||
if cv2.waitKey(1) & 0xFF == ord("s"):
|
||||
break
|
||||
|
||||
camera.release()
|
||||
cv2.destroyAllWindows()
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/python3
|
||||
# tutorial: https://medium.com/@jamesthesken/crop-row-detection-using-python-and-opencv-93e456ddd974
|
||||
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
img = cv2.imread('/home/caroline/Pictures/trees1.png')
|
||||
#cv2.imshow("img",img)
|
||||
b,g,r = cv2.split(img) # split image in blue, green and red channels
|
||||
#get grayscale image by 'amplifying' the color green and getting rid of red & blue
|
||||
gscale = 2*g-r-b
|
||||
|
||||
#Canny edge detection:
|
||||
#1. noise reduction with 5x5 Gaussian filter
|
||||
#2. Finding Intensity Gradient: filtering with sobel kernel in horizintal
|
||||
# & vertical direction to get 1st derivative in horizontal & vertical direction
|
||||
# calculation of edge gradient & direction for each pixel
|
||||
# => getting gradient, magnitude & direction
|
||||
#3. Non-maximum Suppression: scan to remove unwanted pixels (not constituting edge)
|
||||
# checking if pixel is local maximum in its neighbourhood in direction of gradient
|
||||
# => binary image with hin edges
|
||||
#4. Hysteresis Thresholding: threshold values maxVal & minVal to determine edges & non-edges (discarded)
|
||||
# edges between values are only edges if connected to to "sure-edges"
|
||||
# also removes small pixels as edges are assumed to be long lines
|
||||
gscale = cv2.Canny(gscale,280,290,apertureSize = 3) #(input image, minVal, maxVal, aperture_size=size of Sobel kernel to find image gradients: default=3)
|
||||
# default L2gradient=False => Edge_Gradient(G)=|G_x|+|G_y|; True => Edge_Gradient(G)=sqrt(G_x²+G_y²)
|
||||
gscale2 = cv2.Canny(gscale,100,290,apertureSize = 3)
|
||||
gscale3 = cv2.Canny(gscale,250,290,apertureSize = 3)
|
||||
gscale4 = cv2.Canny(gscale,280,350,apertureSize = 3)
|
||||
|
||||
""" plt.figure()
|
||||
plt.plot(), plt.imshow(gscale)
|
||||
plt.title('Canny Edge-Detection Results')
|
||||
plt.xticks([]), plt.yticks([])
|
||||
plt.show() """
|
||||
|
||||
##
|
||||
plt.subplot(221)
|
||||
plt.plot(),plt.imshow(gscale)
|
||||
plt.title('Canny Edge-Detection 1'), plt.xticks([]), plt.yticks([])
|
||||
plt.subplot(222)
|
||||
plt.plot(),plt.imshow(gscale2)
|
||||
plt.title('Canny Edge-Detection 2'), plt.xticks([]), plt.yticks([])
|
||||
plt.subplot(223)
|
||||
plt.plot(),plt.imshow(gscale3)
|
||||
plt.title('Canny Edge-Detection 3'), plt.xticks([]), plt.yticks([])
|
||||
plt.subplot(224)
|
||||
plt.plot(),plt.imshow(gscale4)
|
||||
plt.title('Canny Edge-Detection 4'), plt.xticks([]), plt.yticks([])
|
||||
plt.show()
|
||||
##
|
||||
|
||||
|
||||
size = np.size(gscale) #returns the product of the array dimensions
|
||||
skel = np.zeros(gscale.shape,np.uint8) #array of zeros
|
||||
ret,gscale = cv2.threshold(gscale,128,255,0) #thresholding the image
|
||||
#(grayscale source image, threshod value to classify pixel values, max value, type of thresholding)
|
||||
#output: threshold that was used, thresholded image
|
||||
|
||||
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) # get kernel: (shape,size,anchor=new cv.Point(-1.-1))
|
||||
# anchor position [-1,-1] at center of image, only cross-shaped element depends on anchor position
|
||||
done = False
|
||||
while not done:
|
||||
eroded = cv2.erode(gscale,element) # erodes away boundaries of foreground object & removes small noise
|
||||
temp = cv2.dilate(eroded,element) # increase object area
|
||||
temp = cv2.subtract(gscale,temp) # subtract images of same type & depth
|
||||
skel = cv2.bitwise_or(skel,temp)
|
||||
gscale = eroded.copy()
|
||||
zeros = size - cv2.countNonZero(gscale)
|
||||
if zeros==size:
|
||||
done = True
|
||||
|
||||
|
||||
lines = cv2.HoughLines(skel,1,np.pi/180,130) #lines=vector storing lines (r,theta)
|
||||
#(output of edge detector, resolution of r in pixels, resolution of theta in rad, threshold: min # of intersections, srn & stn)
|
||||
a,b,c = lines.shape
|
||||
|
||||
#draw the lines
|
||||
for i in range(a):
|
||||
rho = lines[i][0][0]
|
||||
theta = lines[i][0][1]
|
||||
a = np.cos(theta)
|
||||
b = np.sin(theta)
|
||||
x0 = a*rho
|
||||
y0 = b*rho
|
||||
x1 = int(x0 + 1000*(-b))
|
||||
y1 = int(y0 + 1000*(a))
|
||||
x2 = int(x0 - 1000*(-b))
|
||||
y2 = int(y0 - 1000*(a))
|
||||
|
||||
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2, cv2.LINE_AA)
|
||||
#display lines: image, point1, point2, color, thickness int, line type, shift)
|
||||
|
||||
plt.subplot(121)#OpenCV reads images as BGR, this corrects so it is displayed as RGB
|
||||
plt.plot(),plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
|
||||
plt.title('Row Detection'), plt.xticks([]), plt.yticks([])
|
||||
plt.subplot(122)
|
||||
plt.plot(),plt.imshow(skel,cmap='gray')
|
||||
plt.title('Skeletal Image'), plt.xticks([]), plt.yticks([])
|
||||
plt.show()
|
||||
Executable
+265
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# run bagfile: rosbag play -l 'filename'
|
||||
# run python script: python3 initial_test.py
|
||||
|
||||
import roslib
|
||||
import sys
|
||||
import argparse
|
||||
import rospy
|
||||
import cv2
|
||||
import time
|
||||
from std_msgs.msg import String
|
||||
from sensor_msgs.msg import Image
|
||||
from cv_bridge import CvBridge, CvBridgeError
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
#import hsv_toolbar_ros as tb
|
||||
|
||||
LAB_boolean = True
|
||||
HSV_boolean = True
|
||||
RGB_boolean = True
|
||||
|
||||
def rescale_frame(frame, percent):
|
||||
width = int(frame.shape[1] * percent/ 100)
|
||||
height = int(frame.shape[0] * percent/ 100)
|
||||
dim = (width, height)
|
||||
return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
|
||||
|
||||
#class Image_Segmentation():
|
||||
|
||||
|
||||
class Image_Receiver():
|
||||
|
||||
def __init__(self):
|
||||
#rospy.init_node('zed_image_left', anonymous=True)
|
||||
self.bridge = CvBridge()
|
||||
rospy.Subscriber("/zed/zed_node/left/image_rect_color", Image, self.callback)
|
||||
plt.ion()
|
||||
|
||||
def region_selection(self,image):
|
||||
rows, columns = image.shape[:2]
|
||||
bottom_left = [0*columns /6, 6*rows / 6]
|
||||
top_left = [1.5*columns / 6, 2*rows /6]
|
||||
bottom_right = [6*columns / 6, 6*rows / 6]
|
||||
top_right = [4.5*columns / 6, 2*rows / 6]
|
||||
polygons = np.array([[bottom_left, top_left, top_right, bottom_right]], dtype=np.int32)
|
||||
|
||||
mask = np.zeros_like(image)
|
||||
cv2.fillPoly(mask,polygons,(255,255,255))
|
||||
masked_image = cv2.bitwise_and(image,mask)
|
||||
return masked_image
|
||||
|
||||
def otsu(self,images):
|
||||
otsu_threshold = []
|
||||
image_result = []
|
||||
for i in range(len(images)):
|
||||
threshold, result = cv2.threshold(images[i], 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||
otsu_threshold.append(threshold)
|
||||
image_result.append(result)
|
||||
return otsu_threshold, image_result
|
||||
|
||||
def display_binary(self,images,color_space, rescale):
|
||||
color_spaces = ", ".join(color_space)
|
||||
images_rescaled = images
|
||||
if rescale == True:
|
||||
for i in range(len(images)):
|
||||
images_rescaled[i] = rescale_frame(images[i],30)
|
||||
horizontal_concat = []
|
||||
for i in range(1,len(images),3):
|
||||
horizontal_concat.append(np.concatenate((images_rescaled[i-1], images_rescaled[i], images_rescaled[i+1]), axis=1))
|
||||
cube_concat = horizontal_concat[0]
|
||||
for i in range(1,len(horizontal_concat)):
|
||||
cube_concat = np.concatenate((cube_concat,horizontal_concat[i]), axis=0)
|
||||
cv2.imshow('Binary Otsu Images for '+color_spaces+' color space', cube_concat)
|
||||
|
||||
def hough(self,images,RGBimage):
|
||||
RGBimages = []
|
||||
hough_lines = []
|
||||
for i in range(len(images)):
|
||||
RGBimages.append(RGBimage)
|
||||
for i in range(len(images)):
|
||||
lines = cv2.HoughLines(images[i],1,np.pi/180,200)
|
||||
|
||||
for rho,theta in lines[0]:
|
||||
a = np.cos(theta)
|
||||
b = np.sin(theta)
|
||||
x0 = a*rho
|
||||
y0 = b*rho
|
||||
x1 = int(x0 + 1000*(-b))
|
||||
y1 = int(y0 + 1000*(a))
|
||||
x2 = int(x0 - 1000*(-b))
|
||||
y2 = int(y0 - 1000*(a))
|
||||
|
||||
cv2.line(RGBimages[i],(x1,y1),(x2,y2),(0,0,255),2,cv2.LINE_AA)
|
||||
hough_lines.append(lines)
|
||||
return RGBimages, hough_lines
|
||||
|
||||
def hough_linesP(self,image, binary_images):
|
||||
RGBimages = []
|
||||
hough_lines = []
|
||||
for i in range(len(binary_images)):
|
||||
RGBimages.append(image)
|
||||
for i in range(len(binary_images)):
|
||||
lines = cv2.HoughLinesP(binary_images[i],2,np.pi/120,10,minLineLength=250,maxLineGap=75)
|
||||
for line in lines:
|
||||
x1,y1,x2,y2 = line[0]
|
||||
cv2.line(image,(x1,y1),(x2,y2),(255,255,0),3)
|
||||
line_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)
|
||||
hough_lines.append(lines)
|
||||
#cv2.imshow("line_img",image)
|
||||
return image, hough_lines
|
||||
|
||||
def hough_lineP(self,image, green_image):
|
||||
lines = cv2.HoughLinesP(green_image,2,np.pi/120,10,minLineLength=250,maxLineGap=75)
|
||||
for line in lines:
|
||||
x1,y1,x2,y2 = line[0]
|
||||
cv2.line(image,(x1,y1),(x2,y2),(255,255,0),3)
|
||||
line_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)
|
||||
#cv2.imshow("line_img",image)
|
||||
return image
|
||||
|
||||
def Rgb_space(self,image):
|
||||
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
R,G,B = cv2.split(rgb_image)
|
||||
hist = self.histogram(rgb_image,["R","G","B"])
|
||||
|
||||
def Lab_space(self,image):
|
||||
lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
|
||||
L,A,B = cv2.split(lab_image)
|
||||
hist = self.histogram(lab_image,["L","A","B"])
|
||||
|
||||
return lab_image,L,A,B
|
||||
|
||||
def Hsv_space(self,image):
|
||||
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
|
||||
H,S,V = cv2.split(hsv_image)
|
||||
hist = self.histogram(hsv_image,["H","S","V"])
|
||||
|
||||
"""
|
||||
plt.clf()
|
||||
plt.subplot(131)
|
||||
plt.title("L")
|
||||
plt.imshow(L)
|
||||
plt.subplot(132)
|
||||
plt.title("a")
|
||||
plt.imshow(A)
|
||||
plt.subplot(133)
|
||||
plt.title("b")
|
||||
plt.imshow(B)
|
||||
plt.draw()
|
||||
plt.pause(0.005)
|
||||
"""
|
||||
return hsv_image,H,S,V
|
||||
|
||||
def callback(self, image_data):
|
||||
try:
|
||||
self.left_image = self.bridge.imgmsg_to_cv2(image_data, "bgr8")
|
||||
except CvBridgeError as e :
|
||||
print(e)
|
||||
rescaled = rescale_frame(self.left_image,75)
|
||||
denoised_image = cv2.GaussianBlur(rescaled, (5, 5), 0)
|
||||
cv2.imshow("original_image", denoised_image)
|
||||
print('Image size: {width}x{height}'.format(width=rescaled.shape[0],height=rescaled.shape[1]))
|
||||
roi_image = self.region_selection(denoised_image)
|
||||
color_image = roi_image
|
||||
channels = []
|
||||
color_spaces = []
|
||||
if RGB_boolean == True:
|
||||
color_image,chR,chG,chB = self.Lab_space(roi_image)
|
||||
channels.extend([chR,chG,chB])
|
||||
color_spaces.extend(["R","G","B"])
|
||||
if LAB_boolean == True:
|
||||
color_image,chL,chA,chB = self.Lab_space(roi_image)
|
||||
channels.extend([chL,chA,chB])
|
||||
color_spaces.extend(["L","A","B"])
|
||||
if HSV_boolean == True:
|
||||
color_image,chH,chS,chV = self.Hsv_space(roi_image)
|
||||
channels.extend([chH,chS,chV])
|
||||
color_spaces.extend(["H","S","V"])
|
||||
if channels and color_spaces:
|
||||
otsu_threshold, otsu_result = self.otsu(channels)
|
||||
print("Obtained thresholds: ",otsu_threshold)
|
||||
self.display_binary(otsu_result,color_spaces,True)
|
||||
#hough_images, lines = self.hough(otsu_result,roi_image)#
|
||||
#hough_images, lines = self.hough_linesP(roi_image, otsu_result)
|
||||
#self.display_binary(hough_images,color_spaces,False)
|
||||
hough_lines = self.hough_lineP(otsu_result[0],otsu_result[0])
|
||||
cv2.imshow("Hough Line P Function", hough_lines)
|
||||
cv2.waitKey(3)
|
||||
|
||||
#frame_threshold = cv2.inRange(color_image, (tb.low_H, tb.low_S, tb.low_V), (tb.high_H, tb.high_S, tb.high_V))
|
||||
|
||||
#cv2.imshow(window_capture_name, cv_image)
|
||||
#cv2.imshow(window_detection_name, frame_threshold)
|
||||
|
||||
def histogram(self,image,name):
|
||||
# create the histogram plot, with three lines, one for
|
||||
# each color
|
||||
# plt.clf()
|
||||
plt.figure()
|
||||
plt.xlim([0, 256])
|
||||
for i in range(3):
|
||||
hist = cv2.calcHist([image],[i],None,[256], [0,256])
|
||||
plt.plot(hist)
|
||||
plt.legend(name)
|
||||
plt.title("Color Histogram")#of legend color space
|
||||
plt.xlabel("Color value")
|
||||
plt.ylabel("Pixel count")
|
||||
plt.show()
|
||||
return hist
|
||||
|
||||
#plt.draw()
|
||||
plt.pause(0.005)
|
||||
cv2.waitKey(0) # übergangsweise
|
||||
plt.close('all')
|
||||
|
||||
def main():
|
||||
|
||||
#Start the node imageprocessing
|
||||
rospy.init_node('zed_image_left', anonymous=True)
|
||||
#calls the function that OpenCV requires
|
||||
detector = Image_Receiver()
|
||||
|
||||
rate = rospy.Rate(10) # 10hz
|
||||
#TODOPublish the offset value obtained from the front subscriber
|
||||
|
||||
|
||||
#Keep the node alive unti; keyboard interrupt
|
||||
try:
|
||||
rospy.spin()
|
||||
except KeyboardInterrupt:
|
||||
rospy.loginfo("Detector node terminated.")
|
||||
print("Shutting down")
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
# Execution guard for python files
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
"""
|
||||
|
||||
def imshow(img):
|
||||
cv2.imshow("..",img)
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
img = cv2.imread('/home/andrew/Desktop/camera/crop_row_detection/images/behrImages/first.jpg')
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
|
||||
while True:
|
||||
resized_image = rescale_frame(img,25)
|
||||
#imshow(resized_image)
|
||||
L,A,B=cv2.split(resized_image)
|
||||
cv2.imshow("L_Channel",L) # For L Channel
|
||||
cv2.imshow("A_Channel",A) # For A Channel (Here's what You need)
|
||||
cv2.imshow("B_Channel",B) # For B Channel
|
||||
ch = cv2.waitKey(1)
|
||||
if ch == 27:
|
||||
break
|
||||
cv2.waitKey(5)
|
||||
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
"""
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/python3
|
||||
# https://pyimagesearch.com/2018/07/19/opencv-tutorial-a-guide-to-learn-opencv/
|
||||
# import the necessary packages
|
||||
import cv2
|
||||
import imutils
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
def rescale_frame(frame, percent): # rescale image considering aspect ratio
|
||||
width = int(frame.shape[1] * percent/ 100)
|
||||
height = int(frame.shape[0] * percent/ 100)
|
||||
dim = (width, height)
|
||||
return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
|
||||
# alternative: resized = imutils.resize(image, width=300) => give goal height or width
|
||||
|
||||
def extract_channels(image,color_space):
|
||||
(ch1,ch2,ch3) = cv2.split(image)
|
||||
cv2.imshow("Channel "+color_space[0],ch1)
|
||||
cv2.imshow("Channel "+color_space[1],ch2)
|
||||
cv2.imshow("Channel "+color_space[2],ch3)
|
||||
|
||||
def rotate_bound(image, angle):
|
||||
(h, w) = image.shape[:2] # image dimesnsions
|
||||
(cX, cY) = (w // 2, h // 2) # center of image
|
||||
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0) # neg angle to rotate clockwise
|
||||
cos = np.abs(M[0, 0]) # cos & sin value from rotation matrix
|
||||
sin = np.abs(M[0, 1])
|
||||
# compute the new bounding dimensions of the image
|
||||
nW = int((h * sin) + (w * cos))
|
||||
nH = int((h * cos) + (w * sin))
|
||||
# adjust the rotation matrix to take into account translation
|
||||
M[0, 2] += (nW / 2) - cX
|
||||
M[1, 2] += (nH / 2) - cY
|
||||
# perform the actual rotation and return the image
|
||||
return cv2.warpAffine(image, M, (nW, nH))
|
||||
|
||||
|
||||
# load the input image and show its dimensions, keeping in mind that
|
||||
# images are represented as a multi-dimensional NumPy array with
|
||||
# shape no. rows (height) x no. columns (width) x no. channels (depth)
|
||||
image = cv2.imread('/home/caroline/Pictures/first.jpg') #numpy array
|
||||
|
||||
# resize image ignoring aspect ratio
|
||||
resized_image = cv2.resize(image, (300, 300))
|
||||
cv2.imshow("Fixed Resizing", resized_image)
|
||||
cv2.waitKey(0)
|
||||
|
||||
image = rescale_frame(image,20)
|
||||
|
||||
|
||||
(h, w, d) = image.shape #height=rows, width=columns, depth=channels => 3 for RGB
|
||||
print("width={}, height={}, depth={}".format(w, h, d))
|
||||
# display the image to our screen -- we will need to click the window
|
||||
# open by OpenCV and press a key on our keyboard to continue execution
|
||||
cv2.imshow("Image", image)
|
||||
cv2.waitKey(0)
|
||||
|
||||
# grayscale value 0-255
|
||||
# (B, G, R) with range [0, 255]
|
||||
|
||||
# access the RGB pixel located at x=50, y=100, keepind in mind that
|
||||
# OpenCV stores images in BGR order rather than RGB
|
||||
(B, G, R) = image[100, 50]
|
||||
print("R={}, G={}, B={}".format(R, G, B))
|
||||
|
||||
# array slicing and cropping
|
||||
# extract a 100x100 pixel square ROI (Region of Interest) from the
|
||||
# input image starting at x=320,y=60 at ending at x=420,y=160
|
||||
""" roi = image[60:160, 320:420]
|
||||
cv2.imshow("ROI", roi)
|
||||
cv2.waitKey(0) """
|
||||
|
||||
# transform image into different color spaces and split channels
|
||||
""" image_lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
|
||||
extract_channels(image_lab,"LAB") # lightness, red/green value, blue/yellow value => very vast color space
|
||||
cv2.waitKey(0)
|
||||
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # hue:color 0°-360°, saturation: amount of grey 0-1, value: brightness/intensity 0-1
|
||||
extract_channels(image_hsv,"HSV")
|
||||
cv2.waitKey(0) """
|
||||
|
||||
# rotate image
|
||||
# loop over rotation angles without cutting image
|
||||
""" for angle in np.arange(0, 360, 30): # range [0, 360] in 15° increments
|
||||
rotated = rotate_bound(image, angle)
|
||||
cv2.imshow("Rotated", rotated)
|
||||
cv2.waitKey(0) """
|
||||
|
||||
# blurring: reduce high-frequency noise => gaussianBlur function
|
||||
blurred = cv2.GaussianBlur(image, (11, 11), 0) # 11x11 kernel: larger kernel create more blurry images
|
||||
cv2.imshow("Blurred", blurred)
|
||||
cv2.waitKey(0)
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/python3
|
||||
#https://pyimagesearch.com/2017/01/02/rotate-images-correctly-with-opencv-and-python/
|
||||
|
||||
import numpy as np
|
||||
import argparse
|
||||
import imutils
|
||||
import cv2
|
||||
|
||||
# construct the argument parse and parse the arguments
|
||||
""" ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-i", "--image", required=True,
|
||||
help="path to the image file")
|
||||
args = vars(ap.parse_args()) """
|
||||
|
||||
image = cv2.imread('/home/caroline/Pictures/first.jpg')
|
||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
gray = cv2.GaussianBlur(gray, (3, 3), 0)
|
||||
edged = cv2.Canny(gray,90, 200)
|
||||
|
||||
resized_image = cv2.resize(edged, (800, 800))
|
||||
cv2.imshow("Edged", resized_image)
|
||||
cv2.waitKey(0)
|
||||
|
||||
# further tutorial on rotating and cutting off...
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/python3
|
||||
# Crop row navigation for autonomous field robot
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import sys
|
||||
|
||||
def rescale_frame(frame, percent): # rescale image considering aspect ratio
|
||||
width = int(frame.shape[1] * percent/ 100)
|
||||
height = int(frame.shape[0] * percent/ 100)
|
||||
dim = (width, height)
|
||||
return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
|
||||
|
||||
image = cv2.imread('/home/caroline/Pictures/first.jpg')
|
||||
image=rescale_frame(image, 20)
|
||||
|
||||
### TBD: add Gaussian Blurr
|
||||
|
||||
### Image Segmentation
|
||||
|
||||
## RGB
|
||||
# apply mask that generates grayscale image highlighting green ROIs
|
||||
b,g,r = cv2.split(image)
|
||||
gscale = 2*g-r-b
|
||||
|
||||
""" cv2.imshow("Image after ExG mask is applied", gscale)
|
||||
cv2.waitKey(0) """
|
||||
|
||||
|
||||
# obtain binary image by applying intensity threshold
|
||||
""" color = ('b','g','r')
|
||||
for i,col in enumerate(color):
|
||||
hist = cv2.calcHist(image,[i],None,[256], [0,256])# image histogram
|
||||
plt.plot(hist, color=col)
|
||||
plt.title('Histogram of initial image')
|
||||
plt.show()
|
||||
cv2.waitKey(0) """
|
||||
|
||||
|
||||
""" hist2 = cv2.calcHist(gscale,[0],None,[256], [0,256])# image histogram
|
||||
plt.plot(hist2,'k')
|
||||
plt.title('Histogram of grayscale image')
|
||||
plt.show()
|
||||
cv2.waitKey(0) """
|
||||
|
||||
ret2,gscale2 = cv2.threshold(gscale,127,225,0)
|
||||
ret,gscale = cv2.threshold(gscale,180,200,0)
|
||||
""" cv2.imshow("Binary image", gscale)
|
||||
cv2.waitKey(0) """
|
||||
|
||||
while True:
|
||||
Hori = np.concatenate((gscale, gscale2), axis=1) # left and right image
|
||||
cv2.imshow('Comparing Different Thresholds', Hori)
|
||||
cv2.waitKey(1)
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
## YUV
|
||||
# get U and V Layer
|
||||
image_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
|
||||
(Y,U,V) = cv2.split(image_yuv)
|
||||
task=2 #1: Layers; 2: histogram, 3: binary image, 4: combined layers
|
||||
if task==1:
|
||||
while True:
|
||||
cv2.imshow("U-Layer",U)
|
||||
cv2.imshow("V-Layer",V)
|
||||
cv2.waitKey(1)
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
elif task==2:
|
||||
for i in range(2):
|
||||
hist_yuv = cv2.calcHist(image_yuv,[i],None,[256], [0,256])
|
||||
plt.plot(hist_yuv)
|
||||
plt.legend('U' 'V')
|
||||
plt.title('Histogram of U and V Layer')
|
||||
plt.show()
|
||||
cv2.waitKey(0)
|
||||
|
||||
elif task==3:
|
||||
ret_u,binary_u = cv2.threshold(U,120,130,0)
|
||||
ret_v,binary_v = cv2.threshold(V,125,135,0)
|
||||
while True:
|
||||
binary_uv = np.concatenate((binary_u, binary_v), axis=1)
|
||||
cv2.imshow('U and V layer as binary image', binary_uv)
|
||||
cv2.waitKey(1)
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
elif task==4:
|
||||
uv_combi = cv2.bitwise_and(binary_u,binary_v)
|
||||
cv2.imshow('U and V layer as binary image', uv_combi)
|
||||
cv2.waitKey(0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user