2016年6月11日 星期六

III專題 06/11



Home 點 距離   右上corner 的珠子的距離為 (27,0) mm

珠子的直徑大概11 mm...

目前第一步是會先移到到左上角的第一顆.....然後藉由演算法算出來的座標去移動

然後最後在移動回左上角的第一顆的位置....再回到home....


G code 的 格式

  • G0 is rapid move. It moves the machine to the given coordinates, with the expectation that no machining takes place during the move (tool not in contact with the stock). Unless the mode is changed by other G-code commands, the coordinates are absolute: G0 X10 moves to X=10, G0 X10 again does nothing because you're already at X=10. If coordinates for two or more axes are given, the machine moves in a straight line to the specified point. Starting from X=0, Y=0, the command G0 X10 Y10 moves diagonally to X=10, Y=10. Even if the axes have different maximum speeds and accelerations, the machine still moves them in a coordinated fashion, so that the move is linear. Only the axes specified move; the others do not change position.
  • G1 is linear move. It moves the machine to the given coordinates, with the expectation that the tool would be cutting. It's exactly like G0, except it has an extra parameter, F, that gives the feed rate (the speed at which to move). The speed is expressed in units per minute (mm per minute or inches per minute, depending on mode -- default mm/min). So, with the machine at X=0, Y=0, the command G1 X100 Y100 F200 moves it diagonally to X=100, Y=100, a distance of about 141 mm, at 200 mm/min, so it takes about 43 seconds to get there.

  • G2 and G3 are arc moves (clockwise and counter-clockwise), and they're described very well here. I would use only the I J form and not even bother with the R form.[2]

我目前是採用  G91...  相對的模式....
G90Switch to absolute distance modeCoordinates are now relative to the origin of the currently active coordinate system, as opposed to the current position. G0 X-10 Y5 will move to the position 10 units to the left and 5 above the origin X0,Y0. cf. G91 below.All Grbl versions
G91Switch to incremental distance modeCoordinates are now relative to the current position, with no consideration for machine origin. G0 X-10 Y5 will move to the position 10 units to the left and 5 above the current position. cf. G90 above.All Grbl versions











2016年6月7日 星期二

3D scan code study , step 5

import numpy as np
import cv2
import math
def camxyzparam(pxpy):
    ##################################################### function for calculating X,Y, and Z of points
    fcl=0.00269816   #pixel size for left camera Focal Length
    fcr=0.00269816  #pixel size for right camera
    tetl=0.26179938779914943653855361527329  
                                #left camera rotation angle around Y axis (15 deg)
    tetr=-0.26179938779914943653855361527329    #right camera rotation angle
    phil=0     #left camera rotation angle around X axis
    phir=0
    x0l=250     # left camera translation in X direction
    x0r=-250
    y0l=0      # right camera translation in Y direction
    y0r=0
    z0l=0  
    z0r=0
    ccddr=3.67    #focal lenght right camera mm
    ccddl=3.67    #focal lenght left camera
    ###################################################
    x0=x0r 
    y0=y0r 
    z0=z0r 
    x1=-(pxpy[0]-960)*fcr   #px1  ,  960 為  1920/2,  fcr 為right focus length
    y1=(pxpy[1]-540)*fcr   #py1     , 540 為  1080/2,  fcl 為left focus length
    z1=ccddr
    alfa=tetr
    beta=phir
    gama=0
    Rright = np.array([[math.cos(gama), -math.sin(gama), 0],[math.sin(gama), math.cos(gama), 0],[   0, 0, 1]])
    Rright = Rright.dot(np.array([[1 ,0 ,0 ], [0 ,math.cos(beta), -math.sin(beta)] , [0 ,math.sin(beta), math.cos(beta)]]))
    Rright = Rright.dot(np.array([[math.cos(alfa),0 ,-math.sin(alfa)], [0, 1, 0], [math.sin(alfa), 0, math.cos(alfa)]]))
    XA=np.array(Rright.dot(([[x1],[y1],[z1]]))+([[x0],[ y0],[ z0]]))
    x1=XA[0]   
    y1=XA[1]   
    z1=XA[2] 
    x2=x0l
    y2=y0l
    z2=z0l
    xh3=-(pxpy[2]-960)*fcl   #px2
    yh3=(pxpy[3]-540)*fcl   #py2
    zh3=ccddl
    alfa=tetl
    beta=phil
    gama=0
    Rleft = np.array([[math.cos(gama), -math.sin(gama), 0],[math.sin(gama), math.cos(gama), 0],[   0, 0, 1]])
    Rleft = Rleft.dot(np.array([[1 ,0 ,0 ], [0 ,math.cos(beta), -math.sin(beta)] , [0 ,math.sin(beta), math.cos(beta)]]))
    Rleft = Rleft.dot(np.array([[math.cos(alfa),0 ,-math.sin(alfa)], [0, 1, 0], [math.sin(alfa), 0, math.cos(alfa)]]))
    XB=np.array(Rleft.dot(([[xh3],[yh3],[zh3]]))+([[x2],[y2],[z2]]))
    x3=XB[0]   
    y3=XB[1]   
    z3=XB[2]
    u=[float(x1)-x0,float(y1)-y0,float(z1)-z0]
    v=[float(x3-x2),float(y3-y2),float(z3-z2)]
    p=[x0,y0,z0]
    q=[x2,y2,z2]
    w=np.subtract(p,q)
    denomst=np.inner(v,u)*np.inner(v,u)-np.inner(v,v)*np.inner(u,u)
    s=(np.inner(w,u)*np.inner(v,v)-np.inner(v,u)*np.inner(w,v))/denomst
    t=(np.inner(v,u)*np.inner(w,u)-np.inner(u,u)*np.inner(w,v))/denomst
    xyz=np.divide((np.add(p,np.multiply(s,u))+np.add(q,np.multiply(t,v))),2)
    abdist=np.add(p,np.multiply(s,u))-np.add(q,np.multiply(t,v))
    return xyz,abdist

###
numpy.inner(ab)
Inner product of two arrays.
####
w = p − q (11)



XYZ,abdist=camxyzparam([960,540,960,540]) # test function
print XYZ

#==================================================================
ii=0
rightcod=[]
import csv

with open('rightcod', 'rb') as csvfile:
     xyreader = csv.reader(csvfile, delimiter=',', quotechar='|')
     for row in xyreader:
         rightcod.append([int(row[0]),int(row[1]),int(row[2])])


##  rightcod 的內容
167461 (亮度值), 0(xx), 0 (yy)
39489, 0, 1
7685, 0, 2
2049, 0, 3
4098, 0, 4
##

a = np.array(rightcod)
aa=a[a[:,0].argsort(),]
aaa, right_idx=np.unique(aa[:,0],return_index=True)

m=aaa.size
print 'Total points from right camera= ',m
rightcodmean=np.zeros([m,3])

for ii in range(0,m-1):
    rightcodmean[ii]=[aaa[ii],np.mean(aa[right_idx[ii]:right_idx[ii+1],1]),np.mean(aa[right_idx[ii]:right_idx[ii+1],2])]




numpy.mean(aaxis=Nonedtype=Noneout=Nonekeepdims=False)[source]
Compute the arithmetic mean along the specified axis.

csvfile.close()
#==================================================================
ii=0
leftcod=[]
with open('leftcod', 'rb') as csvfile:
     xyreader = csv.reader(csvfile, delimiter=',', quotechar='|')
     for row in xyreader:
         leftcod.append([int(row[0]),int(row[1]),int(row[2])])

a = np.array(leftcod)
aa=a[a[:,0].argsort(),]
aaa, left_idx=np.unique(aa[:,0],return_index=True)

m=aaa.size
print 'Total points left= ',m
leftcodmean=np.zeros([m,3])

for ii in range(0,m-1):
    leftcodmean[ii]=[aaa[ii],np.mean(aa[left_idx[ii]:left_idx[ii+1],1]),np.mean(aa[left_idx[ii]:left_idx[ii+1],2])]

codes=np.append(rightcodmean[:,0],leftcodmean[:,0])  #  左邊和右邊的 gray code 亮度
unicod=np.unique(codes[:])


##


numpy.unique(arreturn_index=Falsereturn_inverse=Falsereturn_counts=False)[source]
Find the unique elements of an array.

Examples
>>>
>>> np.unique([1, 1, 2, 2, 3, 3])
array([1, 2, 3])
>>> a = np.array([[1, 1], [2, 3]])
>>> np.unique(a)
array([1, 2, 3])


maskright=np.in1d(unicod,rightcodmean[:,0])
###


numpy.in1d(ar1ar2assume_unique=Falseinvert=False)[source]
Test whether each element of a 1-D array is also present in a second array.
Returns a boolean array the same length as ar1 that is True where an element of ar1 is inar2 and False otherwise.



maskrightindex=np.searchsorted(rightcodmean[:,0],unicod)

####


numpy.searchsorted(avside='left'sorter=None)[source]
Find indices where elements should be inserted to maintain order.
Find the indices into a sorted array a such that, if the corresponding elements in v were inserted before the indices, the order of a would be preserved.

Examples
>>>
>>> np.searchsorted([1,2,3,4,5], 3)
2
>>> np.searchsorted([1,2,3,4,5], 3, side='right')
3
>>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
array([0, 5, 1, 2])

maskleft=np.in1d(unicod,leftcodmean[:,0])
maskleftindex=np.searchsorted(leftcodmean[:,0],unicod)


camrcolor=cv2.imread("CAMR/CAM001.png");
camrcolol=cv2.imread("CAML/CAM101.png");



kk=0
m=unicod.size
print 'Total points on left and right cameras= ',m
matchpixels =  np.zeros([4])
xyz=np.zeros([m,3])
xyzcolor=np.zeros([m,3],dtype=np.uint8)
# finding common points between two cameras and calculating XYZ
for ii in range(0,m-1):
    if (maskleft[ii] and maskright[ii]):
        matchpixels[0]=rightcodmean[maskrightindex[ii],1]
        matchpixels[1]=rightcodmean[maskrightindex[ii],2]
        matchpixels[2]=leftcodmean[maskleftindex[ii],1]
        matchpixels[3]=leftcodmean[maskleftindex[ii],2]
        # 找到 相同點....然後達到這點在左右camera 的x,y 座標
        xyzdata,abdist=camxyzparam([matchpixels[0],matchpixels[1],matchpixels[2],matchpixels[3]])
        #check if the points is in specified limit and distance between rays less than some values
        if ((np.linalg.norm(abdist)<20) and (xyzdata[2]>400 and xyzdata[2]<2000 and xyzdata[0]>-500 and xyzdata[0]<500)):
           xyz[kk,0]= -xyzdata[0]
           xyz[kk,1]= -xyzdata[1]
           xyz[kk,2]= -xyzdata[2]
           # color info from average of image from both cameras
           xyzcolor[kk,0]= (camrcolor[int(matchpixels[1]),int(matchpixels[0]),2]/2+camrcolol[int(matchpixels[3]),int(matchpixels[2]),2]/2)
           xyzcolor[kk,1]= (camrcolor[int(matchpixels[1]),int(matchpixels[0]),1]/2+camrcolol[int(matchpixels[3]),int(matchpixels[2]),1]/2)
           xyzcolor[kk,2]= (camrcolor[int(matchpixels[1]),int(matchpixels[0]),0]/2+camrcolol[int(matchpixels[3]),int(matchpixels[2]),0]/2)
           kk=kk+1




print 'Total points = ',kk-1

# open a PLY file to save the XYZ and colors of point cloud
ff=open(captdirect+"/"+"pointcloud.ply","w")
ff.write('ply\n')
ff.write('format ascii 1.0\n')
ff.write('comment PCL generated\n')
ff.write('element vertex %d\n'%(kk-1))
ff.write('property float x\n')
ff.write('property float y\n')
ff.write('property float z\n')
ff.write('property uchar red\n')
ff.write('property uchar green\n')
ff.write('property uchar blue\n')
ff.write('end_header\n')


for ii in range(0,kk-1):
    ff.write(str(xyz[ii,0])+" "+str(xyz[ii,1])+" "+str(xyz[ii,2])+" "+str(xyzcolor[ii,0])+" "+str(xyzcolor[ii,1])+" "+str(xyzcolor[ii,2])+"\n")    

ff.close()
print 'calcxyzcolor Done!'


===================================================
paper  :

0.8.2 Ray Triangulation Given one pixel in image I1 and its corresponding pixel in image I2, two rays are formed as described above, and their intersection is computed. In practice, the triangulation of two rays in 3D space can be considered as an ill-posed problem since quite often the two rays do not intersect ’exactly’ but rather pass by one another in close proximity. In order to overcome this limitation, the segment perpendicular to the two rays with the shorted distance is computed, and the middle point of the segment is considered to be the intersection point. Figure 12 shows an example where the segment ab is the shortest line connecting the two rays A and B. The mid-point p is considered to be the intersection point.

Computation of the Intersection Point: Consider two lines in 3D space A and B passing through points p and q, with direction vectors ~u and ~v respectively, and let the two closest points on the lines be a and b, as defined in Equation 5 and Equation 6, where s and t are scalar values.  The segment connecting a and b is perpendicular to the lines, hence the dot product of their vectors is equal to 0 as follows, 


a = p + s ∗ ~u (5)
b = q + t ∗ ~v (6)
The segment connecting a and b is perpendicular to the lines, hence the dot product of their vectors is equal to 0 as follows,
(a − b).~u = 0 (7)
 (a − b).~v = 0 (8) 

and with Equations 5 and 6, the Equations 7 and 8 become,
~w.~u + s ∗ ~u.~u − t ∗ ~v.~u = 0 (9)
 ~w.~v + s ∗ ~v.~u − t ∗ ~v.~v = 0 (10)

w = p − q (11)




Ref : http://arxiv.org/pdf/1406.6595v1.pdf

八皇后的演算法



#include <stdio.h>
#include <stdlib.h>

void queens(int x);
void print(void);

unsigned int n, num;
char** checkerboard;
int* column;
int* right;
int* left;

假設n 為 4....

int main(void)
{
    int i, j;

    printf("請輸入 n 的大小: ");
    scanf("%d", &n);

    // 動態分配記憶體
    column = malloc(sizeof(int) * n);
    right = malloc(sizeof(int) * (2 * n - 1));
    left = malloc(sizeof(int) * (2 * n - 1));
    checkerboard = malloc(sizeof(char*) * n);

    // 變數初始化
    num = 0;
    for (i = 0; i < n; i++)
    {
        column[i] = 1;

        checkerboard[i] = malloc(sizeof(char) * n);
        for (j = 0; j < n; j++)
        {
            checkerboard[i][j] = 'x';
        }
    }

    for (i = 0; i < 2 * n - 1; i++)  //  i從  0 到 6 
    {
        right[i] = left[i] = 1;   //  先初始化為1
    }

    queens(0);   // 先排一個皇后

    printf("\n總共有 %d 種排法\n\n", num);

    // 釋放記憶體空間
    for (i = 0; i < n; i++)
    {
        free(checkerboard[i]);
    }

    free(checkerboard);
    free(column);
    free(right);
    free(left);

    system("pause");
}

void queens(int x)   // 一開始x 為 0 ,  下次進來會變成  1, 2, 3
{
    if (x < n)  //  n 為 4
    {
        int i;
        for (i = 0; i < n; i++) //  0 到 3
        {
            int j = i - x + n - 1;  // 右邊的x 座標, i為0,  x為0,  就是3
            int k = i + x;          // 左邊的x 座標, i為0,  x為0,  就是0
                                    // 右邊的x 座標, i為1,  x為0,  就是4
                                    // 左邊的x 座標, i為1,  x為0,  就是1

                                    // 右邊的x 座標, i為2,  x為0,  就是5
                                    // 左邊的x 座標, i為2,  x為0,  就是2

                                    // 右邊的x 座標, i為3,  x為0,  就是6
                                    // 左邊的x 座標, i為3,  x為0,  就是3

// 右邊的x 座標, i為0, x為1, 就是2
                                    // 左邊的x 座標, i為0,  x為1,  就是1
                                    // 右邊的x 座標, i為1,  x為1,  就是3
                                    // 左邊的x 座標, i為1,  x為1,  就是2

                                    // 右邊的x 座標, i為2,  x為1,  就是4
                                    // 左邊的x 座標, i為2,  x為1,  就是3

                                    // 右邊的x 座標, i為3,  x為1,  就是5
                                    // 左邊的x 座標, i為3,  x為1,  就是4

// 他使用 left 和 right array 來排除 左下角和 右下角的case
 //   假設   (col, row) -> (i,x) 
 // example 1 :  (1,2) 和 (2,1)   就是相衝突...
  //            兩個(i,x)帶進去算出來的k 都是 3  -> 所以這次的 left[k] 就已經被清成0
  //             不會成立
 // example 2 :  (1,2) 和 (2,3)   就是相衝突...
  //            兩個(i,x)帶進去算出來的j 都是 2  -> 所以這次的 right[j] 就已經被清成0
  //    


            if (column[i] && right[j] && left[k])
            {
                // 標記皇后位置, 並遞迴放置下一個
                column[i] = right[j] = left[k] = 0;
                checkerboard[x][i] = 'Q';

                queens(x + 1);

                column[i] = right[j] = left[k] = 1;
                checkerboard[x][i] = 'x';
            }
        }
    }
    else
    {
        // 輸出棋盤
        print();
        num++;
    }
}

void print(void)
{
    int i, j;

    printf("\n");
    for(i = 0; i < n; i++)
    {
        for(j = 0; j < n; j++)
        {
            printf("%c", checkerboard[i][j]);
        }

        printf("\n");
    }
}

2016年6月2日 星期四

電腦base 的示波器



http://www.perytech.com/Oscilloscope/Oscilloscope_tw.htm

depth image



Depth Map from Stereo Images

Goal

In this session,
  • We will learn to create depth map from stereo images.

Basics

In last session, we saw basic concepts like epipolar constraints and other related terms. We also saw that if we have two images of same scene, we can get depth information from that in an intuitive way. Below is an image and some simple mathematical formulas which proves that intuition. (Image Courtesy :
Calculating depth
The above diagram contains equivalent triangles. Writing their equivalent equations will yield us following result:
disparity = x - x' = \frac{Bf}{Z}
x and x' are the distance between points in image plane corresponding to the scene point 3D and their camera center. B is the distance between two cameras (which we know) and f is the focal length of camera (already known). So in short, above equation says that the depth of a point in a scene is inversely proportional to the difference in distance of corresponding image points and their camera centers. So with this information, we can derive the depth of all pixels in an image.
So it finds corresponding matches between two images. We have already seen how epiline constraint make this operation faster and accurate. Once it finds matches, it finds the disparity. Let’s see how we can do it with OpenCV.

Code

Below code snippet shows a simple procedure to create disparity map.
import numpy as np
import cv2
from matplotlib import pyplot as plt

imgL = cv2.imread('tsukuba_l.png',0)
imgR = cv2.imread('tsukuba_r.png',0)

stereo = cv2.createStereoBM(numDisparities=16, blockSize=15)
disparity = stereo.compute(imgL,imgR)
plt.imshow(disparity,'gray')
plt.show()
Below image contains the original image (left) and its disparity map (right). As you can see, result is contaminated with high degree of noise. By adjusting the values of numDisparities and blockSize, you can get better results.

Ref : https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_depthmap/py_depthmap.html#py-depthmap