-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathImagesToArray.py
155 lines (109 loc) · 5.1 KB
/
ImagesToArray.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
########################################################################
# ImagesToArray #
########################################################################
# This script is designed to take a given directory and output an array
# of all the points in all the images appended with a Z axis value
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
import time
import os
DIRECTORY = '/home/pi/Desktop/ScannerDev/'
allPoints = [] # List of all points in all images
filteredPoints = [] # List of points when duplicates removed
resolution = 1 # FOR EXAMPLE, from project global
minSep = 83 # Dist between camera and laser at extremities
maxTravel = 315 # Max distance laser can move
xPixels = 640 # PROJECT GLOBAL
yPixels = 480 # PROJECT GLOBAL
#--------------------- FUNCTION DEFINITIONS ---------------------#
### Image to list conversion #
def pointCorrection(xVal, yVal, zVal, camNum):
# Correction for xy distortion on each layer
global minSep, xPixels, yPixels
# Make centre of image 0,0
xVal = xVal - (xPixels/2)
yVal = yVal - (yPixels/2)
# Distortion for each camera is different for a shared plane
if camNum == 1:
xVal = round((xVal*0.598*(minSep + zVal)/xPixels),3)
yVal = round((yVal*0.448*(minSep + zVal)/yPixels),3)
elif camNum == 2:
xVal = round((xVal*0.598*(minSep + (maxTravel - zVal))/ xPixels),3)
yVal = round((yVal*0.448*(minSep + (maxTravel - zVal))/ yPixels),3)
return (xVal, yVal)
def imageToPoints(image, camNum, zVal):
# Takes an image and appends to allPoints list with given z value
ret, discrImage = cv.threshold (image, 127, 255, 0)
#height, width = discrImage.shape
# Add a line of white values to the top of the image.
# This ensures that the binary outer contour works.
# It is removed later before writing to point cloud.
# Order is [y,x] i.e. [row, column]
discrImage[0,:] = 255 # 1st row, and the whole x range
img, vectImage, heirarchy = cv.findContours(discrImage, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# from all the contours, extract the largest based off of the area
contImage = max(vectImage, key=cv.contourArea)
# Append all dimensions of point to list of all points
for point in contImage:
xVal, yVal = tuple(point[0])
"""allPoints[i][0] = float(xVal)
allPoints[i][1] = float(yVal)
allPoints[i][2] = float(zVal)"""
# Skip top line of the image (white values written previously)
if xVal > 3:
# X and Y correction
xVal, yVal = pointCorrection(xVal, yVal, zVal, camNum)
point3D = (float(xVal), float(yVal), float(zVal))
allPoints.append(point3D)
return
def imagesToList(pathToImages):
# Iterates through directory and processes each image into array
global resolution
for img in os.listdir(pathToImages):
# Filters out any rogue files (e.g. hidden)
if img.endswith(".png"):
image = cv.imread(DIRECTORY + 'TestPhotos/' + img, cv.IMREAD_GRAYSCALE)
#print image
if len(image) == 0:
print(DIRECTORY+'TestPhotos/'+img, "could not be read!")
return # can't go on with an invalid image
print ('Processing ' + img)
camNum, imgNum = os.path.splitext(img)[0].split('img')
camNum = int(camNum)
imgNum = int(imgNum)
zVal = imgNum*resolution
imageToPoints(image, camNum, zVal)
else: print ('File ' + img +''' not of format [x]img[y].png''')
print ('Processed all images')
### Removal of duplicates #
def theCondition(xs,ys):
# working with squares, 2.5e-05 is 0.005*0.005
return sum((x-y)*(x-y) for x,y in zip(xs,ys)) > 2.5e-05
def filterPoints(checkValues,condition):
print (str(len(checkValues)) + ' points')
print ('Removing duplicates...')
start = time.time()
result = []
i = 0
for value in checkValues:
i = i + 1
print ('\rProcessing ' + str(i) + ' of ' + str(len(checkValues)), end='')
if all(condition(value,other) for other in result if other[2] == value[2]):
result.append(value)
end = time.time()
timeElapsed = round(end - start)
print ('\nProcessed in ' + str(timeElapsed) + ' seconds')
print (str(len(result)) + ' points remaining')
return result
### Overall function #
def getPoints(pathToImages):
imagesToList(pathToImages)
return filterPoints(allPoints, theCondition)
#----------------------------- MAIN -----------------------------#
if __name__ == '__main__':
# For testing purposes
pathToImages = DIRECTORY + 'TestPhotos/'
print('Extracting points from images...')
filteredPoints = getPoints(pathToImages)
print(np.array(filteredPoints))