您好,登錄后才能下訂單哦!
這篇文章主要介紹“processing怎么實現視覺抓取小程序”,在日常操作中,相信很多人在processing怎么實現視覺抓取小程序問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”processing怎么實現視覺抓取小程序”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
用processing寫一個簡單的視覺抓取小程序:識別紅藍綠色塊并順序抓放。
import processing.serial.*; import processing.video.*; Serial Port; Capture cam; float[][] kernel ={{0.111,0.111,0.111}, {0.111,0.111,0.111}, {0.111,0.111,0.111} };//卷積核 //中間像素的灰度值等于周圍像素的紅色分量減去藍綠色分量的平均值 //從而使沒有紅色特征的像素灰度值變為零 //相當于濾鏡的效果,修改卷積核的參數,可以達到不一樣的效果 int sub_x=0,sub_y=0;//物體中心的像素坐標 float pre_x=0,pre_y=0;//前一幀物體中心的像素坐標 float tar_x=80,tar_y=80;//目標坐標,機械手的坐標 boolean event=false;//坐標計算事件 int c=0; void setup()//初始化 { String portName = Serial.list()[0]; Port = new Serial(this, portName, 115200);//連接串口 size(640,480);//屏幕大小 String[] cameras = Capture.list(); printArray(cameras);//打印可使用的相機 cam = new Capture(this, cameras[0]); cam.start();//啟動相機 frameRate(30);//幀率 Port.write("G5 B90\r\n"); Port.write("G28\r\n"); Port.write("G1 X80 Y80 Z40\r\n"); Port.write("G5 B50\r\n");//移動到初始位置 delay(6000);//延遲,避免攝像頭剛打開時的波動 } void draw()//循環 { if (cam.available() == true) { cam.read(); image(cam, 0, 0, width, height); cam.loadPixels(); int sum_x=0,sum_y=0;//所有紅色像素坐標的和 int m=1;//紅色像素的個數 for(int y=1;y<cam.height-1;y++)//排除第一行、最后一行、第一列、最后一列像素(這幾個地方周圍的像素不完整) { for(int x=1;x<cam.width-1;x++)//經過所有像素 { float sum=0;//最終的灰度值 for(int ky =-1;ky<=1;ky++) { for(int kx=-1;kx<=1;kx++)//周圍9個像素(包括自身) { int pos =(y+ky)*cam.width+(x+kx);//將xy坐標換算成pixels[]數組中的位置,pixels[]數組是可以直接調用的儲存像素的一維數組(從左到右從上到下) int R = (cam.pixels[pos]>> 16) & 0xFF; //取顏色分量,與red()功能相似 int G = (cam.pixels[pos] >> 8) & 0xFF; int B = cam.pixels[pos] & 0xFF; float val=0; switch(c)//順序抓取紅藍綠色塊 { case 0: val =R-1.5*B-1.5*G; break; case 1: val =B-1.5*R-1.5*G; break; case 2: val =G-0.5*B-1*R; break; } //1.5為比例系數,改大可以讓紅色更突出 sum +=kernel[ky+1][kx+1]*val;//計算灰度值 } } if(sum>0)//新的灰度值非零 { sum_x=sum_x+x; sum_y=sum_y+y;//累加坐標 m=m+1;//計數 } } } pre_x=sub_x; pre_y=sub_y;//前一幀的物體中心 sub_x=sum_x/m; sub_y=sum_y/m;//取平均,計算出物體中心像素坐標 cam.updatePixels(); fill(#FF0000); } line(sub_x,0,sub_x,480); line(0,sub_y,640,sub_y);//作物體中心的兩條交叉線 if(abs(sub_x-pre_x)<5&&abs(sub_y-pre_y)<5&&sub_x>5&&sub_y>5)//判斷是否在移動(波動小于5個像素即為靜止),是否存在物體(沒有物體時默認為0,為避免波動,這里設置成5) { if(event==true)//如果物體存在,機械手靜止,且事件被觸發,則進行計算 { tar_x=tar_x-(0.0625*sub_x-20); tar_y=tar_y-(15-0.0625*sub_y);//把像素坐標轉化成絕對坐標,根據實際比例 event=false;//關閉計算事件,即只執行一次計算 Port.write("G1 X"+tar_x+" Y"+tar_y+"\r\n");//移動到目標位置 delay(100);//延遲,減小波動 } } else //如果機械手在移動,觸發計算事件,但不執行計算,為機械手靜止時計算做準備 event=true; /*由于機械手的通訊以及動作上有延遲,速度遠趕不上攝像頭對圖像識別的速度, 所以僅讓機械臂在靜止時進行一次計算*/ if(sub_x<5&&sub_y<5) { if(c<3) c=c+1; else c=0; } float mx=tar_x; float my=tar_y+32;//手抓中心對的坐標,攝像頭和手抓有32的y偏移量 if(sub_x>315&&sub_x<325&&sub_y>235&&sub_y<245)//當物體在畫面中心時(+-5個像素) { //執行以下動作 Port.write("G1 X"+mx+'Y'+my+"Z12 F1200\r\n"); delay(1500);//充分延時 for(int i=50;i<=150;i+=5) { Port.write("G5 B"+i+"\r\n"); delay(50); } delay(500); Port.write("G1 Z30\r\n"); delay(1000); switch(c)//順序擺放紅藍綠色塊 { case 0: Port.write("G1 X150 Y120\r\n");break; case 1: Port.write("G1 X150 Y100\r\n");break; case 2: Port.write("G1 X150 Y80\r\n");break; } delay(1500); Port.write("G1 Z10\r\n"); delay(500); for(int j=150;j>=50;j-=5) { Port.write("G5 B"+j+"\r\n"); delay(50); } delay(500); Port.write("G1 X80 Y80 Z40\r\n"); delay(1500); if(c<3) c=c+1; else c=0; } println(tar_x); println(tar_y); }
到此,關于“processing怎么實現視覺抓取小程序”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。