Herkese merhaba bu yazıda OpenCv ile arduino’ya sinyaller yollayıp ikisinin haberleşmesini sağlayacağız. OpenCv ile ilgili bir kaç örnek yaptık bu örneklerde temel olarak renk ayrımı yapmayı görmüş olduk şimdi bu elde ettiğimiz bilgileri bir tık daha yukarı çıkarıp arduino ile birleştirerek daha somut projeler elde etmeye çalışalım. Bu yapacağımız ufak proje şöyle olacak OpenCv ile web cam’imizden görüntüyü alacağız ve bu görüntünün ekranda ki konumuna göre şuan için basitce bir servoya hareket verebiliriz belki sonraki aşamalarda daha farklı işler de yaparız, temel olarak şuan için servo dönderelim.
Daha önceden yazdığımız kodları kullanacağız yine, sadece farklı olarak seri porttan veri gönderme kodlarını ekleyeceğiz şimdi o kodlara bakalım;
#include <Windows.h>//seri porttan veri gönderimi için import edilmeli kesinlikle
hserial = CreateFile(L"COM5", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);//burada com5 önemli arduino da seçilen ile aynı port olmalı if (hserial != INVALID_HANDLE_VALUE)//eğer seri bağlantı varsa { printf("port acildi \n"); GetCommState(hserial, &seriParametre);//seri bağlantı isteği seriParametre.BaudRate = CBR_256000;//bağlantı hızımı meşhur 9600'ün aynısı en yüksek olanı seçtim ben seriParametre.ByteSize = 8;//bayt boyutu 8 bit standart seriParametre.Parity = NOPARITY;//parity biti olmasın seriParametre.StopBits = ONESTOPBIT;//durma biti bunların temel olarak ne yaptıklarını bilmiyorum ama default olarak ayarlıyoruz SetCommState(hserial, &seriParametre); } //------------------------------------------------veri gönderme kodları------------------------------------------------- char deger[1];//char tipinde bir değişken tanımlıyoruz deger[0] = '1';//veriyi karşıya char olarak atıyoruz WriteFile(hserial, deger, strlen(deger), &btsIO, NULL);//veriyi seri porta bırakarak gönderiyoruz
Yukarıda temel olarak ilk aşamada gerekli hazırlıkları yaptık ve veri gönderme kısmında ise verilerimizi seri porta gönderdik gönderdiğimiz verileri seri porttan arduino ile okuduğumuz zaman iki teknoloji haberleşmiş olacak. Temel olarak mantık bu şekilde seri porta veriyi bırak ordan veriyi oku bu sadece bu iki teknoloji için değil seri porttan veri okuyabilen tüm teknolojiler için aynı dikkat ettiyseniz burada ekstradan 3. parti bir kütüphane kurulumu filan olmadı arduino kısmında da olmayacak.
Şimdi bir önceki yazıda ki kodlar ile bu yazıda ki kodları birleştiripi tek bir parça yapalım;
#include "stdafx.h" #include <opencv2/opencv.hpp> #include <Windows.h> using namespace cv; HANDLE hserial; DCB seriParametre; DWORD btsIO; void seriPort() { hserial = CreateFile(L"COM6", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hserial != INVALID_HANDLE_VALUE) { printf("port acildi \n"); GetCommState(hserial, &seriParametre); seriParametre.BaudRate = CBR_256000; seriParametre.ByteSize = 8; seriParametre.Parity = NOPARITY; seriParametre.StopBits = ONESTOPBIT; SetCommState(hserial, &seriParametre); } } int main() { seriPort();//seri ayar fonksiyonumuzu çağırdık char deger[1]; VideoCapture video(0); Mat okunan,hsv,renkTespit; int minB=0, minG=0, minR=0, maxB=255, maxG=255, maxR=255; namedWindow("ayar",CV_WINDOW_AUTOSIZE);//tracbar'ları ekranda göstermek için kullanacağımız pencere createTrackbar("maviMin","ayar",&minB,255);//scalar değerleri için kullanacağımız trackbar'lar createTrackbar("yesilMin","ayar",&minG,255); createTrackbar("kirmiziMin", "ayar", &minR, 255); createTrackbar("maivMax", "ayar", &maxB, 255); createTrackbar("yesilMax", "ayar", &maxG, 255); createTrackbar("kirmiziMax", "ayar", &maxR, 255); namedWindow("ayar"); Moments mom;//bahsettiğim moments fonksiyonu bize değerleri sağlayacak float alan, x, y; while (true) { video.read(okunan);//kameradan görüntü alıyoruz imshow("orjinal görüntü",okunan);//elde edilen görüntüyü ekranda gösteriyoruz, göstermek zorunda değiliz cvtColor(okunan,hsv,CV_BGR2HSV);//hsv renk formatına çeviriyoruz imshow("hsv", hsv);//elde edilen görüntüyü ekranda gösteriyoruz, göstermek zorunda değiliz inRange(hsv,Scalar(minB,minG,minR),Scalar(maxB,maxG,maxR),renkTespit);//tresholding işlemini yani siyah ve beyaz'a indirgiyoruz imshow("tespit edilen", renkTespit);//elde edilen görüntüyü ekranda gösteriyoruz, göstermek zorunda değiliz mom = moments(renkTespit);//moments fonksiyonu ile değerlere ulaşıp atama işlemini yapıyoruz alan = mom.m00;//tespit edilen beyaz kısmın alanı x = mom.m10 / alan;//tespit edilen beyaz kısmın x koordinatı y = mom.m01 / alan;//tespit edilen beyaz kısmın y koordinatı printf("alan ---> %f\n",alan);//ekranda görmek için printf("y ---> %f\n",y); printf("x ---> %f\n", x); if (x > 150)//x eksenine göre işlem şartı { deger[0] = '1';//eğer şart sağlandıysa 1 gönder WriteFile(hserial, deger, strlen(deger), &btsIO, NULL); } if (x < 150) { deger[0] = '2';//eğer şart sağlandıysa 2 gönder WriteFile(hserial, deger, strlen(deger), &btsIO, NULL); } if (waitKey(10) == 27)//döngüden çıkış şartı esc tuşuna basılırsa çıksın { break; } } return 0; }
Şimdi bir de arduino kodlarına bakalım;
#include <Servo.h>//servo kütüphanesi Servo servo;//servo türünden değişken void setup() { Serial.begin(256000);//hızımız diğer tarafla aynı olmalı servo.attach(3);//3 numaralı pini ayarladım servo.write(90);//ilk başta 90 dereceye ayarlasın } void loop() { if(Serial.parseInt()==1)//eğer seri porttan 1 okursa { //açıyı 5 derece yap servo.write(5); } if(Serial.parseInt()==2)//eğer seri porttan 1 okursa { //açıyı 355 derece yap servo.write(355); } }
Bu yazıda görüntü işleme yardımıyla servo motor hareket ettime işlemini gerçekleştirmeye çalıştık buradan hedef objenin koordinat bilgilerine göre işlem yaptırdık objenin direk koordinat bilgileri de seri porta yollanabilir ya da objenin alan bilgilerinide elde etmiştik istersek o veriyi kullanarakta işlemler yapılabilir. Herkese iyi çalışmalar.