2016年5月31日 星期二
install opencv on rpi3
Ref : http://www.pyimagesearch.com/2016/04/18/install-guide-raspberry-pi-3-raspbian-jessie-opencv-3/
3D scan code study , step 3 and step 4
step3 : threshold
=============================================
import numpy as np
import cv2
horzlino=1920
vertlino=1080
import os
import glob
img_names = glob.glob("CAML/*.png")
img1=cv2.imread(img_names[0],cv2.IMREAD_GRAYSCALE)
ii=50
# adjusting the threshold for processing area and eliminating shadows
# use left and right arrow key to adjust and press 'q' when finished
while True:
ret,img1th = cv2.threshold(img1,ii,255,cv2.THRESH_TOZERO)
cv2.putText(img1th,"Threshold is "+str(ii), (10,50), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
cv2.imshow("PWindow2",img1th)
k = cv2.waitKey(0)
if k == ord('q'):
break
elif k == ord('a'):
ii=ii+1
elif k == ord('b'):
ii=ii-1
cv2.destroyAllWindows()
np.save(captdirect+"/"+"thresholdleft" , ii)
img_names = glob.glob("CAMR/*.png")
img1=cv2.imread(img_names[0],cv2.IMREAD_GRAYSCALE)
ii=50
while True:
ret,img1th = cv2.threshold(img1,ii,255,cv2.THRESH_TOZERO)
cv2.putText(img1th,"Threshold is "+str(ii), (10,50), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
cv2.imshow("PWindow2",img1th)
k = cv2.waitKey(0)
if k == ord('q'):
break
elif k == ord('a'):
ii=ii+1
elif k == ord('b'):
ii=ii-1
cv2.destroyAllWindows()
np.save("thresholdright" , ii) # Save an array to a binary file in NumPy .npy format.
print 'Threshold Done!'
================================================================
step4 : calcxy1xy2
================================================================
import numpy as np
import cv2
import os
import glob
old_settings = np.seterr(all='ignore')
horzlino=1920
vertlino=1080
Direct="CAMR/"
rightcamcode=np.load(Direct+"coloccod.npy" ) # step 2 result, right camcode,1920x1080x2 維度
[x][y][0] -> 放水平方向的 gray code 影像
[x][y][1] -> 放垂直方向的 gray code 影像
Direct="CAML/"
leftcamcode=np.load(Direct+"coloccod.npy" ) # step 2 result, left camcode
thresholdleft=np.load("thresholdleft.npy" ) # step 3 output thr val
thresholdright=np.load("thresholdright.npy" ) # step 3 output thr val
imgmaskrightf ="CAMR/CAM001.png"
img1=cv2.imread(imgmaskrightf,cv2.IMREAD_GRAYSCALE) # Loads image in grayscale mode
ret,img1 = cv2.threshold(img1,thresholdright,255,cv2.THRESH_TOZERO) # TOZERO .. 小於thr 變成黑色...大於thr 維持不變
imgmaskright=np.divide(img1,img1)
=======================================================================
# np.divide
numpy.divide(x1, x2[, out]) = <ufunc 'divide'>
np.divide(img1,img1) -> 得到mask 只有0或是1 的影像
===================================================================
imgmaskleftf ="CAML/CAM101.png"
img1=cv2.imread(imgmaskleftf,cv2.IMREAD_GRAYSCALE)
ret,img1 = cv2.threshold(img1,thresholdleft,255,cv2.THRESH_TOZERO)
imgmaskleft=np.divide(img1,img1)
# 換成左邊做一次
kkl=0 # kk coef for left
kkr=0 # kk coef for right
colocright=[] # color array for right
colocleft=[] # color array for left
leftsrt=[]
rightsrt=[]
# finding similar points in both camera bast on projected pattern
for ii in range(0, horzlino): # horzlino-> 1920
for jj in range(0, vertlino): # vertlino-> 1080
if (rightcamcode[jj][ii][0]!=0 and rightcamcode[jj][ii][1]!=0 and imgmaskright[jj][ii]!=0):
colocright.append(np.uint32([rightcamcode[jj][ii][0]+rightcamcode[jj][ii][1]*1024 ,ii, jj]))
#colocright 為一維陣列... 一次加三個值... color val,x , y
rightsrt.append(rightcamcode[jj][ii][0]+rightcamcode[jj][ii][1]*1024)
kkl=kkl+1
if (leftcamcode[jj][ii][0]!=0 and leftcamcode[jj][ii][1]!=0 and imgmaskleft[jj][ii]!=0):
colocleft.append(np.uint32([leftcamcode[jj][ii][0]+leftcamcode[jj][ii][1]*1024,ii ,jj]))
leftsrt.append(leftcamcode[jj][ii][0]+leftcamcode[jj][ii][1]*1024)
kkr=kkr+1
print kkr,kkl
np.savetxt("leftcod" , colocleft ,fmt='%d', delimiter=', ', newline='\n')
np.savetxt("rightcod" , colocright ,fmt='%d', delimiter=', ', newline='\n')
#
numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='',comments='# ')
import operator
colocrightsrt=[]
colocleftsrt=[]
colocrightsrt=sorted(colocright, key=operator.itemgetter(0))
colocleftsrt=sorted(colocleft, key=operator.itemgetter(0))
rightsrtt=sorted(rightsrt)
leftsrtt=sorted(leftsrt)
================================
#
===========================
kkr=0
np.save("colocrightsrt" , colocrightsrt)
np.save("colocleftsrt" , colocleftsrt)
newlistl=np.unique(leftsrtt)
np.savetxt("colocleftsrtuniq" , newlistl ,fmt='%d', delimiter=', ', newline='\n')
newlistr=np.unique(rightsrtt)
np.savetxt("colocrightsrtuniq" , newlistr ,fmt='%d', delimiter=', ', newline='\n')
#finding common points in both cameras
camunio=np.intersect1d(newlistl,newlistr)
#
numpy.intersect1d(ar1, ar2, assume_unique=False)[source]
kkl=0
kkr=0
kk=0
matchpixels=np.zeros((np.size(camunio),4), dtype=np.int16)
matchpixels[kk][0]=0
matchpixels[kk][1]=0
matchpixels[kk][2]=0
matchpixels[kk][3]=0
for i in camunio:
while (newlistr[kkr] != i):
kkr=kkr+1
matchpixels[kk][0]=colocrightsrt[kkr][1] # right camera x pixel coordinate
matchpixels[kk][1]=colocrightsrt[kkr][2] # right camera y pixel coordinate
while (newlistl[kkl] != i):
kkl=kkl+1
matchpixels[kk][2]=colocleftsrt[kkl][1] #left camera x pixel coordinate
matchpixels[kk][3]=colocleftsrt[kkl][2] #left camera y pixel coordinate
kk=kk+1
# 找到相同的亮度的座標...記錄left camera 的 (x,y) 放到 matchpixel[0][1]
記錄right camera 的 (x,y) 放到 matchpixel[2][3]
np.savetxt("colocuniq" , matchpixels ,fmt='%d', delimiter=',', newline='\n')
print 'calcxy1xy2 Done!'
================================================================
import numpy as np
import cv2
import os
import glob
old_settings = np.seterr(all='ignore')
horzlino=1920
vertlino=1080
Direct="CAMR/"
rightcamcode=np.load(Direct+"coloccod.npy" ) # step 2 result, right camcode,1920x1080x2 維度
[x][y][0] -> 放水平方向的 gray code 影像
[x][y][1] -> 放垂直方向的 gray code 影像
Direct="CAML/"
leftcamcode=np.load(Direct+"coloccod.npy" ) # step 2 result, left camcode
thresholdleft=np.load("thresholdleft.npy" ) # step 3 output thr val
thresholdright=np.load("thresholdright.npy" ) # step 3 output thr val
imgmaskrightf ="CAMR/CAM001.png"
img1=cv2.imread(imgmaskrightf,cv2.IMREAD_GRAYSCALE) # Loads image in grayscale mode
ret,img1 = cv2.threshold(img1,thresholdright,255,cv2.THRESH_TOZERO) # TOZERO .. 小於thr 變成黑色...大於thr 維持不變
imgmaskright=np.divide(img1,img1)
=======================================================================
# np.divide
Divide arguments element-wise.
Parameters: |
x1 : array_like
x2 : array_like
out : ndarray, optional
|
---|---|
Returns: |
y : ndarray or scalar
|
===================================================================
imgmaskleftf ="CAML/CAM101.png"
img1=cv2.imread(imgmaskleftf,cv2.IMREAD_GRAYSCALE)
ret,img1 = cv2.threshold(img1,thresholdleft,255,cv2.THRESH_TOZERO)
imgmaskleft=np.divide(img1,img1)
# 換成左邊做一次
kkl=0 # kk coef for left
kkr=0 # kk coef for right
colocright=[] # color array for right
colocleft=[] # color array for left
leftsrt=[]
rightsrt=[]
# finding similar points in both camera bast on projected pattern
for ii in range(0, horzlino): # horzlino-> 1920
for jj in range(0, vertlino): # vertlino-> 1080
if (rightcamcode[jj][ii][0]!=0 and rightcamcode[jj][ii][1]!=0 and imgmaskright[jj][ii]!=0):
colocright.append(np.uint32([rightcamcode[jj][ii][0]+rightcamcode[jj][ii][1]*1024 ,ii, jj]))
#colocright 為一維陣列... 一次加三個值... color val,x , y
rightsrt.append(rightcamcode[jj][ii][0]+rightcamcode[jj][ii][1]*1024)
kkl=kkl+1
if (leftcamcode[jj][ii][0]!=0 and leftcamcode[jj][ii][1]!=0 and imgmaskleft[jj][ii]!=0):
colocleft.append(np.uint32([leftcamcode[jj][ii][0]+leftcamcode[jj][ii][1]*1024,ii ,jj]))
leftsrt.append(leftcamcode[jj][ii][0]+leftcamcode[jj][ii][1]*1024)
kkr=kkr+1
print kkr,kkl
np.savetxt("leftcod" , colocleft ,fmt='%d', delimiter=', ', newline='\n')
np.savetxt("rightcod" , colocright ,fmt='%d', delimiter=', ', newline='\n')
#
numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='',comments='# ')
fname : filename or file handle
If the filename ends in .gz, the file is automatically saved in compressed gzip format. loadtxt understands gzipped files transparently.
X : array_like
Data to be saved to a text file.
import operator
colocrightsrt=[]
colocleftsrt=[]
colocrightsrt=sorted(colocright, key=operator.itemgetter(0))
colocleftsrt=sorted(colocleft, key=operator.itemgetter(0))
rightsrtt=sorted(rightsrt)
leftsrtt=sorted(leftsrt)
================================
#
numpy.sort
- numpy.sort(a, axis=-1, kind='quicksort', order=None)
Parameters: |
a : array_like
axis : int or None, optional
kind : {‘quicksort’, ‘mergesort’, ‘heapsort’}, optional
order : str or list of str, optional
|
---|---|
Returns: |
sorted_array : ndarray
|
kkr=0
np.save("colocrightsrt" , colocrightsrt)
np.save("colocleftsrt" , colocleftsrt)
newlistl=np.unique(leftsrtt)
np.savetxt("colocleftsrtuniq" , newlistl ,fmt='%d', delimiter=', ', newline='\n')
newlistr=np.unique(rightsrtt)
np.savetxt("colocrightsrtuniq" , newlistr ,fmt='%d', delimiter=', ', newline='\n')
#finding common points in both cameras
camunio=np.intersect1d(newlistl,newlistr)
#
Find the intersection of two arrays.
Return the sorted, unique values that are in both of the input arrays.
Parameters: |
ar1, ar2 : array_like
assume_unique : bool
|
---|---|
Returns: |
intersect1d : ndarray
|
>>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1]) array([1, 3])
kkl=0
kkr=0
kk=0
matchpixels=np.zeros((np.size(camunio),4), dtype=np.int16)
matchpixels[kk][0]=0
matchpixels[kk][1]=0
matchpixels[kk][2]=0
matchpixels[kk][3]=0
for i in camunio:
while (newlistr[kkr] != i):
kkr=kkr+1
matchpixels[kk][0]=colocrightsrt[kkr][1] # right camera x pixel coordinate
matchpixels[kk][1]=colocrightsrt[kkr][2] # right camera y pixel coordinate
while (newlistl[kkl] != i):
kkl=kkl+1
matchpixels[kk][2]=colocleftsrt[kkl][1] #left camera x pixel coordinate
matchpixels[kk][3]=colocleftsrt[kkl][2] #left camera y pixel coordinate
kk=kk+1
# 找到相同的亮度的座標...記錄left camera 的 (x,y) 放到 matchpixel[0][1]
記錄right camera 的 (x,y) 放到 matchpixel[2][3]
np.savetxt("colocuniq" , matchpixels ,fmt='%d', delimiter=',', newline='\n')
print 'calcxy1xy2 Done!'
2016年5月30日 星期一
3D scan code study step 1 and step 2
SL3DS1.projcapt.py
=================================================
import cv2
import sys
CV_CAP_PROP_BRIGHTNESS=10
CV_CAP_PROP_CONTRAST=11
CV_CAP_PROP_SATURATION=12
CV_CAP_PROP_EXPOSURE=15
CV_CAP_PROP_WHITE_BALANCE=17
## video capture right camera
video_capture0 = cv2.VideoCapture(0)
video_capture0.set(CV_CAP_PROP_BRIGHTNESS,30.0)
video_capture0.set(CV_CAP_PROP_CONTRAST,5.0)
video_capture0.set(CV_CAP_PROP_SATURATION,100.0)
video_capture0.set(CV_CAP_PROP_EXPOSURE,-8.0)
video_capture0.set(CV_CAP_PROP_WHITE_BALANCE,10000.0)
print video_capture0.get(4)
video_capture0.set(3,1920.0) ## horizontal pixels
video_capture0.set(4,1080.0) ## vertical pixels
print video_capture0.get(4) ## check vertical pixel
##video capture left camera
video_capture1 = cv2.VideoCapture(1)
print video_capture1.get(4)
video_capture1.set(3,1920.0)
video_capture1.set(4,1080.0)
print video_capture1.get(4)
print video_capture1.get(9)
video_capture1.set(CV_CAP_PROP_BRIGHTNESS,30.0)
video_capture1.set(CV_CAP_PROP_CONTRAST,5.0)
video_capture1.set(CV_CAP_PROP_SATURATION,100.0)
video_capture1.set(CV_CAP_PROP_EXPOSURE,-8.0)
video_capture1.set(CV_CAP_PROP_WHITE_BALANCE,10000.0)
## camera properties in opencv
##CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
##CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
##CV_CAP_PROP_FPS Frame rate.
##CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() .
##CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode.
##CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras).
##CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras).
##CV_CAP_PROP_SATURATION Saturation of the image (only for cameras).
##CV_CAP_PROP_HUE Hue of the image (only for cameras).
##CV_CAP_PROP_GAIN Gain of the image (only for cameras).
##CV_CAP_PROP_EXPOSURE Exposure (only for cameras).
##CV_CAP_PROP_CONVERT_RGB Boolean flags indicating whether images should be converted to RGB.
##CV_CAP_PROP_WHITE_BALANCE Currently unsupported
##CV_CAP_PROP_RECTIFICATION Rectificat
#show frames from cameras
ret, frame0 = video_capture0.read()
cv2.imshow("cam0", frame0)
ret, frame1 = video_capture1.read()
cv2.imshow("cam1", frame1)
cv2.waitKey(3000)
ret, frame0 = video_capture0.read()
cv2.waitKey(100)
## cv2.imshow("cam0", frame0)
ret, frame1 = video_capture1.read()
cv2.waitKey(100)
cv2.destroyAllWindows()
horzlino=1280
vertlino=720
for ii in range(0,19):
print ii, video_capture1.get(ii)
## open a borderless window for showing projector images as a second display
cv2.namedWindow("Projector Window",cv2.WND_PROP_FULLSCREEN )
cv2.setWindowProperty("Projector Window", 0,1)
cv2.resizeWindow("Projector Window", 1024,768)
cv2.moveWindow("Projector Window", 1025, -2)
## folders for saving images of left and right cameras
import os
try:
os.makedirs(textvalcap+"/"+'CAMR')
except OSError:
pass
try:
os.makedirs(textvalcap+"/"+'CAML')
except OSError:
pass
imggray=np.load('proj.npy')
# Capture images from left and right cameras after showing pattern in projector
for x in range(1, 43): # processing 42 to left and right
cv2.imshow("Projector Window",imggray[:,:,x-1])
filename0 = 'CAMR/CAM0%02d.png'%(x,)
filename1 = 'CAML/CAM1%02d.png'%(x,)
print filename0
ret, frame0 = video_capture0.read()
cv2.waitKey(100)
ret, frame1 = video_capture1.read()
cv2.waitKey(100)
cv2.imwrite(filename0,frame0)
cv2.imwrite(filename1,frame1)
video_capture0.release()
video_capture1.release()
# When everything is done, release the capture
cv2.destroyAllWindows()
print 'pcapture Done!'
========================================================
step 2 : Processing the 42 images of each camera and capture points codes
========================================================
import numpy as np
import cv2
import os
import glob
def imgdesig(img1,img2): #define a function for getting dark and light pattern
old_settings = np.seterr(all='ignore')
img1=cv2.imread(img1,cv2.IMREAD_GRAYSCALE) # 轉成 灰階
ret,img1 = cv2.threshold(img1,10,255,cv2.THRESH_TOZERO) # thr -> 10, max_val -> 255
img2=cv2.imread(img2,cv2.IMREAD_GRAYSCALE) # 轉成 灰階
ret,img2 = cv2.threshold(img2,10,255,cv2.THRESH_TOZERO) # thr -> 10, max_val -> 255
img12=(((img1//2)+(img2//2))) # sum of img1/2 + img2/2
img123=(np.divide(img1,img12))
img123=(np.divide(img123,img123))
return img123 # 會得到 img1 or (img2 + img1)/2 的影像, 而且只有 0和1的影像
# np.divide -> The quotient x1/x2, element-wise. Returns a scalar if both x1 andx2 are scalars
horzlino=1920
vertlino=1080
Direct=captdirect+"/"+"CAMR/"
img_names = glob.glob(Direct+"*.png")
print captdirect
#call for processing the right camera images
execfile("camlcoloc.py")
np.save(Direct+"coloccod" , rightcamcode)
cv2.waitKey(200)
Direct=captdirect+"/"+"CAML/"
img_names = glob.glob(Direct+"*.png")
#call for processing the left camera images
execfile("camlcoloc.py")
np.save(Direct+"coloccod" , rightcamcode)
cv2.destroyAllWindows()
print 'Procimg Done!'
=================================================
import cv2
import sys
CV_CAP_PROP_BRIGHTNESS=10
CV_CAP_PROP_CONTRAST=11
CV_CAP_PROP_SATURATION=12
CV_CAP_PROP_EXPOSURE=15
CV_CAP_PROP_WHITE_BALANCE=17
## video capture right camera
video_capture0 = cv2.VideoCapture(0)
video_capture0.set(CV_CAP_PROP_BRIGHTNESS,30.0)
video_capture0.set(CV_CAP_PROP_CONTRAST,5.0)
video_capture0.set(CV_CAP_PROP_SATURATION,100.0)
video_capture0.set(CV_CAP_PROP_EXPOSURE,-8.0)
video_capture0.set(CV_CAP_PROP_WHITE_BALANCE,10000.0)
print video_capture0.get(4)
video_capture0.set(3,1920.0) ## horizontal pixels
video_capture0.set(4,1080.0) ## vertical pixels
print video_capture0.get(4) ## check vertical pixel
##video capture left camera
video_capture1 = cv2.VideoCapture(1)
print video_capture1.get(4)
video_capture1.set(3,1920.0)
video_capture1.set(4,1080.0)
print video_capture1.get(4)
print video_capture1.get(9)
video_capture1.set(CV_CAP_PROP_BRIGHTNESS,30.0)
video_capture1.set(CV_CAP_PROP_CONTRAST,5.0)
video_capture1.set(CV_CAP_PROP_SATURATION,100.0)
video_capture1.set(CV_CAP_PROP_EXPOSURE,-8.0)
video_capture1.set(CV_CAP_PROP_WHITE_BALANCE,10000.0)
## camera properties in opencv
##CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
##CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
##CV_CAP_PROP_FPS Frame rate.
##CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() .
##CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode.
##CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras).
##CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras).
##CV_CAP_PROP_SATURATION Saturation of the image (only for cameras).
##CV_CAP_PROP_HUE Hue of the image (only for cameras).
##CV_CAP_PROP_GAIN Gain of the image (only for cameras).
##CV_CAP_PROP_EXPOSURE Exposure (only for cameras).
##CV_CAP_PROP_CONVERT_RGB Boolean flags indicating whether images should be converted to RGB.
##CV_CAP_PROP_WHITE_BALANCE Currently unsupported
##CV_CAP_PROP_RECTIFICATION Rectificat
#show frames from cameras
ret, frame0 = video_capture0.read()
cv2.imshow("cam0", frame0)
ret, frame1 = video_capture1.read()
cv2.imshow("cam1", frame1)
cv2.waitKey(3000)
ret, frame0 = video_capture0.read()
cv2.waitKey(100)
## cv2.imshow("cam0", frame0)
ret, frame1 = video_capture1.read()
cv2.waitKey(100)
cv2.destroyAllWindows()
horzlino=1280
vertlino=720
for ii in range(0,19):
print ii, video_capture1.get(ii)
## open a borderless window for showing projector images as a second display
cv2.namedWindow("Projector Window",cv2.WND_PROP_FULLSCREEN )
cv2.setWindowProperty("Projector Window", 0,1)
cv2.resizeWindow("Projector Window", 1024,768)
cv2.moveWindow("Projector Window", 1025, -2)
## folders for saving images of left and right cameras
import os
try:
os.makedirs(textvalcap+"/"+'CAMR')
except OSError:
pass
try:
os.makedirs(textvalcap+"/"+'CAML')
except OSError:
pass
imggray=np.load('proj.npy')
# Capture images from left and right cameras after showing pattern in projector
for x in range(1, 43): # processing 42 to left and right
cv2.imshow("Projector Window",imggray[:,:,x-1])
filename0 = 'CAMR/CAM0%02d.png'%(x,)
filename1 = 'CAML/CAM1%02d.png'%(x,)
print filename0
ret, frame0 = video_capture0.read()
cv2.waitKey(100)
ret, frame1 = video_capture1.read()
cv2.waitKey(100)
cv2.imwrite(filename0,frame0)
cv2.imwrite(filename1,frame1)
video_capture0.release()
video_capture1.release()
# When everything is done, release the capture
cv2.destroyAllWindows()
print 'pcapture Done!'
========================================================
step 2 : Processing the 42 images of each camera and capture points codes
========================================================
import numpy as np
import cv2
import os
import glob
def imgdesig(img1,img2): #define a function for getting dark and light pattern
old_settings = np.seterr(all='ignore')
img1=cv2.imread(img1,cv2.IMREAD_GRAYSCALE) # 轉成 灰階
ret,img1 = cv2.threshold(img1,10,255,cv2.THRESH_TOZERO) # thr -> 10, max_val -> 255
img2=cv2.imread(img2,cv2.IMREAD_GRAYSCALE) # 轉成 灰階
ret,img2 = cv2.threshold(img2,10,255,cv2.THRESH_TOZERO) # thr -> 10, max_val -> 255
img12=(((img1//2)+(img2//2))) # sum of img1/2 + img2/2
img123=(np.divide(img1,img12))
img123=(np.divide(img123,img123))
return img123 # 會得到 img1 or (img2 + img1)/2 的影像, 而且只有 0和1的影像
# np.divide -> The quotient x1/x2, element-wise. Returns a scalar if both x1 andx2 are scalars
horzlino=1920
vertlino=1080
Direct=captdirect+"/"+"CAMR/"
img_names = glob.glob(Direct+"*.png")
print captdirect
#call for processing the right camera images
execfile("camlcoloc.py")
np.save(Direct+"coloccod" , rightcamcode)
cv2.waitKey(200)
Direct=captdirect+"/"+"CAML/"
img_names = glob.glob(Direct+"*.png")
#call for processing the left camera images
execfile("camlcoloc.py")
np.save(Direct+"coloccod" , rightcamcode)
cv2.destroyAllWindows()
print 'Procimg Done!'
============
camlcoloc.py
============
# horzlino = 1920, vertlino = 1080
grayimg=np.zeros((vertlino, horzlino), dtype=np.int16)
rightcamcode=np.zeros((vertlino, horzlino,2), dtype=np.int16)
##=======================================================
#Horizontal gray code
for ii in range(3,22,2):
#range([start], stop[, step])
#range([start], stop[, step])
start
: Starting number of the sequence.stop
: Generate numbers up to, but not including this number.step
: Difference between each number in the sequence.
xx=ii-3
xx=xx//2
filename1 = img_names[ii]
filename2 = img_names[ii-1]
ff=imgdesig(filename1,filename2) # ff 為 img
print 'processing %s...' % filename1, (2**xx)
grayimg=grayimg+(2**xx)*ff
# 當 xx -> 0 (2**xx) -> 1 3
# 當 xx -> 1 (2**xx) -> 2 5
# 當 xx -> 2 (2**xx) -> 4 7
# 當 xx -> 3 (2**xx) -> 8 9
# 當 xx -> 4 (2**xx) -> 16 11
# 當 xx -> 5 (2**xx) -> 32 13
# 當 xx -> 6 (2**xx) -> 64 15
# 當 xx -> 7 (2**xx) -> 128 17
# 當 xx -> 8 (2**xx) -> 256 19
# 當 xx -> 9 (2**xx) -> 512 21
# 當 xx -> 0 (2**xx) -> 1 3
# 當 xx -> 1 (2**xx) -> 2 5
# 當 xx -> 2 (2**xx) -> 4 7
# 當 xx -> 3 (2**xx) -> 8 9
# 當 xx -> 4 (2**xx) -> 16 11
# 當 xx -> 5 (2**xx) -> 32 13
# 當 xx -> 6 (2**xx) -> 64 15
# 當 xx -> 7 (2**xx) -> 128 17
# 當 xx -> 8 (2**xx) -> 256 19
# 當 xx -> 9 (2**xx) -> 512 21
imgbin3=np.zeros((vertlino, horzlino,3), dtype=np.uint8)
for ii in range(0, horzlino):
for jj in range(0, vertlino):
rightcamcode[jj][ii][0]=grayimg[jj][ii]
imgbin3[jj][ii][1]= grayimg[jj][ii]%256
imgbin3[jj][ii][2]= 40*grayimg[jj][ii]//256
imgbin3[jj][ii][0]= 4
img1=(grayimg%255)
cv2.imshow("PWindow2",imgbin3)
cv2.waitKey(100)
##=======================================================
#Vertical gray code
img1=cv2.imread(img_names[0],cv2.IMREAD_GRAYSCALE)
grayimg=(img1*0)+1023
grayimg=grayimg*0 # 把 grayimg 清除為0
for ii in range(23,42,2):
xx=ii-22
xx=xx//2
filename1 = img_names[ii]
filename2 = img_names[ii-1]
ff=imgdesig(filename1,filename2)
print 'processing %s...' % filename1, (2**xx)
grayimg=grayimg+(2**xx)*ff
for ii in range(0, horzlino):
for jj in range(0, vertlino):
rightcamcode[jj][ii][1]=grayimg[jj][ii]
imgbin3[jj][ii][0]= (imgbin3[jj][ii][0]+grayimg[jj][ii]%256)%256
imgbin3[jj][ii][2]= 40*(imgbin3[jj][ii][2]+grayimg[jj][ii]%256)//80
imgbin3[jj][ii][1]= 4
img1=(grayimg%255)
cv2.imshow("PWindow2",imgbin3)
cv2.waitKey(2000)
3D scan 研究筆記 00
1. Projecting gray patterns and capturing images from two cameras "SL3DS1.projcapt.py"
2. Processing the 42 images of each camera and capture points codes " SL3DS2.procimages.py"
3. Adjusting threshold to select masking for areas to be processed "SL3DS3.adjustthresh.py"
4. Find and save similar points in each camera "SL3DS4.calcpxpy.py"
5 Calculate X,Y and Z coordinates of point cloud "SL3DS5.calcxyz.py"
The output is a PLY file with coordinate and color information of points on object surface. You can open PLY files with CAD software like Autodesk products or an open source sofware like Meshlab.
I have also developed a GUI for this software in TKINTER that you can find in step six with two sample data sets . You can find additional information on this subject on the following websites:
Hardware consists of :
1. Two webcameras (Logitech C920C)
2. Infocus LP330 projector
3. Camera and projector stand (made from 3 mm Acrylic plates and 6 mm HDF wood cut with a laser cutter)
The projector is an Infocus LP330 (Native resolution 1024X768) with following specs.Brightness:650 Lumens
Color Light Output:**Contrast (Full On/Off):400:1
Auto Iris:No
Native Resolution:1024x768
Aspect Ratio:4:3 (XGA)
Video Modes:**
Data Modes:MAX 1024x768
Max Power:200 Watts
Voltage:100V - 240V
Size(cm) (HxWxD):6 x 22 x 25
Weight:2.2 kg
Lamp Life(Full Power):1,000 hours
Lamp Type:UHPLamp
Wattage:120 Watts
Lamp Quantity:1
Display Type:2 cm DLP (1)
Standard Zoom Lens:1.25:1
Focus:Manual
Throw Dist (m): 1.5 - 30.5
Image Size(cm):76 - 1971
This video projector is used to project structured light patterns on the object to be scanned. The structured pattern consists of vertical and horizontal white light strips that are saved on a data file and webcams capture those distorted strips.
Preferably use those cameras that are software controllable because you need to adjust focus, brightness, resolution and image quality. It is possible to use DSLR cameras with SDKs that are provided by each brand.
Assembly and tests were conducted in Copenhagen Fablab with its support.
For testing the 3d scan software in this step I add two data sets one is scan of a fish and another is just a plane wall to see the accuracy of it. Open ZIP files and run SL3DGUI.py. For installation check step 2.
For using 3d scan part you need to install two cameras and projector but for other parts just click on the button. For testing the sample data first click on process then threshold, stereo match and finally point cloud. Install Meshlab to see the point cloud.
Q & A :
Q:how do you convert gray code to decimal?
A:Each pixel in projector screen has a horizontal and a vertical gray code, by grayimg=grayimg+(2**xx)*ff in a loop I convert it to decimal. Horizontal and vertical decimal code is then combined to get a unique number for each pixel among 1024*768 pixel of the projector.
colocright.append(np.uint32([rightcamcode[jj][ii][0]+rightcamcode[jj][ii][1]*1024 ,ii, jj])) is the line that combines horizontal and vertical so that global code is equal to horizontal code plus vertical code multiplied with 1024
file "graykod" is my gray to decimal conversion
rightcod and leftcod files have three columns, first column is the decimal code related to projector pixel, second is horizontal pixel coordinate of the camera and third is vertical pixel coordinate of the camera
aa=a[a[:,0].argsort(),] is for sorting based on the decimal code of projector pixels so that makes it easy to find similar projector pixels in left and right camera
if you need more explanation please ask, also please read the references precisely before asking more questions.
Later you can send me your code for checking and debuging. Try to run programs with the fish and wall data
=================================================================
More specifically, the decoding is performed as follows:
• Determine whether a pixel p is lit or not (1 or 0) in the images capturing the projected sequence of patterns encoding the columns.
• Calculate its binary form Bp.
• Convert the binary form Bp into the equivalent decimal number x.
Similarly, the process is repeated for the images capturing the projected sequence of patterns encoding the rows and results in a decimal number y. Thus, (x, y) are the image coordinates of the projector’s pixel corresponding to the pixel being decoded in a camera. By repeating the process for all the cameras, we can map the pixels not only to the projector’s pixels but rather to the other cameras viewing the object. It should be noted that a camera pixel may be mapped to more than one pixels of another camera due to differences between the camera and projector resolutions.
The decoded captured images result in a set of a many-to-many mappings between the pixels of the different cameras. Next, by triangulating the rays corresponding to each pair, a 3D point is computed at their intersection. The projection of this point falls onto the mapped pixels in the different cameras.
file "graykod" is my gray to decimal conversion
rightcod and leftcod files have three columns, first column is the decimal code related to projector pixel, second is horizontal pixel coordinate of the camera and third is vertical pixel coordinate of the camera
aa=a[a[:,0].argsort(),] is for sorting based on the decimal code of projector pixels so that makes it easy to find similar projector pixels in left and right camera
pixel size and focal length are parameters that you should get from camera manufacturer. x0l,x0r,y0l,y0r,z0l,z0r phi and tet are values that should be set based on your geometrical design(installation of cameras)
For calibration you need accurate calibration board and good algorithm. I used a calibration board from a commercial 3d scanner and found out that my settings are accurate enough for me. But if you need accuracy of 100th of millimeter you need calibration. A good calibration board costs more than 1000 Euros!!
I made camera base and stands with a laser cutter so I could have accurate installation of cameras without calibration.
img12=(((img1//2)+(img2//2)))
img123=(np.divide(img1,img12))
img123=(np.divide(img123,img123))
img123=(np.divide(img1,img12))
img123=(np.divide(img123,img123))
Above part is for thresholding the images and make a binary black and white image read page six of this document:
imgbin3[jj][ii][1]= grayimg[jj][ii]%256
imgbin3[jj][ii][2]= 40*grayimg[jj][ii]//256
imgbin3[jj][ii][0]= 4
imgbin3[jj][ii][2]= 40*grayimg[jj][ii]//256
imgbin3[jj][ii][0]= 4
this part is just for demonstration of stripes with different color, so you can omit this part.
Ref : http://www.instructables.com/id/DIY-3D-scanner-based-on-structured-light-and-stere/?ALLSTEPS