Bilgisayarımızın web kamerasından aldığımız görüntüleri soket programlama kullanarak ortak ağdaki soketlere aktarımın nasıl yapıldığını aktaracağız. Bunun için OpenCv kütüphanelerini kullanmak yükümüzü epey azaltacaktır.

Önceki paylaşımlarda soket oluşturup haberleştirme konularına değinildiği için bu yazıda soket nasıl oluşturulur, veri nasıl gönderilir – yakalanır konularına tekrar girmeye gerek yok. Ağırlıklı olarak

c/c++ programlamada  thread -mutex yapısını kullanabilme

– frame yapısını soketler üzerinden aktarmak ve geri oluşturabilmek

– uzak ağdan seçilen nesnenin takibi üzerinde duracağız.

 

 

 

THREAD nedir?

Thread kısaca bir programın iş yapan parçalarıdır. Birden fazla işin aynı anda yapılmasına imkan sağlamaktadır. Biz işlemlerin paralel olarak yapıldığını sansak da aslında işlemler çok sık zaman aralıkları ile dönüşümlü olarak yapılmaktadır. Ancak multicore ortamlarda işlemler  paralel olarak ilerlemektedir. Örneğin film seyrederken ses ile görüntüyü aynı anda algılarız. Burada ses ile görüntü fonksiyonlar ayrı thread ler dir ve paralel çalışmaktadırlar. Aslında yazdığımız çoğu program şimdiye kadar pek farkında olmasak da  tek thread den oluşan bir programdan başka birşey değildir.

 

POSIX thread (pthread) kütüphanelerini kullanarak oluşturulacak programlar concurrent çalışabilmektedir. Böyle bir uygulama yazmanın avantajını multi-processor yada multi-core sistemlerde gözlemlemek daha kolaydır. c++ da thread in nasıl çalıştığını somut olarak gözlemleyebilmek için basit bir ugulama paylaşmakta fayda var.

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
 
void *fonksiyon1( void *ptr );
void *fonksiyon2( void *ptr );
 
int main(int argc, char** argv)
{
     pthread_t thread1, thread2;
 
     int  deger1, deger2;
 
     deger1 = pthread_create( &thread1, NULL, fonksiyon1, NULL);
     deger2 = pthread_create( &thread2, NULL, fonksiyon2, NULL);
 
     while(1){
     }
     exit(0);
}
 
void *fonksiyon1( void *ptr )
{
	while(1){
		printf(" thread1 calisiyor  \n");
		sleep(3);
	}
}
 
void *fonksiyon2( void *ptr )
{
	while(1){
		printf(" thread2 calisiyor \n");
		sleep(1);
	}
}

 

thread kullanımı (örnek 1)sonuç

 

 

MUTEX nedir?

Yukardaki örneğin çıktılarına baktığımızda thread ler belirli bir sıra ile çalışmamakta. Otopilot projemizde aynı anda 3-4 tane thread çalışmaktadır ve bunların devreye girip devre dışı kalmaları mutex yapısını kullanarak kolaylıkla yapılmaktadır. Bu olayı şu şekilde somut bir şekilde anlatabilirim. Kendinizi birer thread olarak düşünün. odanızda rahatlıkla yapmanız gereken işlemleri (odayı da evdeki işlemleri yürütebileceğiniz tek ortam olarak düşünün) yerine getirebiliyorsunuz. Başka birisi gelip(thread) sizin işlemlerinizi sonlandırıp kendi işlemlerini yürütmeye başlayabilir. Siz de boyle bir kargaşa yaşamamak için odanın kilidini (mutex ) kullanabilirsiniz. Odanın içine girdiğinizde mutexi kilitleyip işlemlerinizi bitirdikten sonra mutex i açıp işlemlerini yapma sırasını kuyurktaki threadlara bırakabilirsiniz.  Acil bir durumda odanın kapısını kırıp direk işlemlerini yürütmeye koyabilecek tanımlarda mevcut fakat Otopilotta kullanılmadığından konuyu dahada dallandırmayacağım.

 

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
 
pthread_mutex_t mutex_deneme = PTHREAD_MUTEX_INITIALIZER;
 
void* fonksiyon(void* arg);
void  quit(char* msg, int retval);
 
int sayi=0;
int kontrol_sinyali=0;
 
int main(int argc, char** argv)
{
	pthread_t 	thread_s;
 
	if (pthread_create(&thread_s, NULL, fonksiyon, NULL)) {}
 
	while(1) {
		pthread_mutex_lock(&mutex_deneme);
			if (kontrol_sinyali) {
					printf("sayi: %d\n",sayi);
					kontrol_sinyali = 0;
			}
		pthread_mutex_unlock(&mutex_deneme);
	}
}
 
void* fonksiyon(void* arg)
{
	while(1)
	{
		pthread_mutex_lock(&mutex_deneme);
		sayi++;
		if(sayi%50 == 0){
			kontrol_sinyali=1;
		}
		pthread_mutex_unlock(&mutex_deneme);
		usleep(30000);
	}
}

mutex örneğinde iki fonksiyon mutex ler vasıtası ile sıra ile çalışmaktadır. Teki sayıyı teker teker arttırmakta diğeri ise sayı 50 nin katı olduğunda ekrana yazdırmaktadır. Programın çıktısı aşağıdaki gibi olmaktadır.

mutex sonuç

 

 TCP/IP Video aktarımı – Obje takibi

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Yukarıdaki resimlerde görüldüğü gibi araç üzerine servolardan iki eksenli nesne takibi için bir mekanizma yaptık. Sistem araç üzerine yazılan bir serverdan servoların ucuna takılan kameradan istenilen ip ye video yayını yapacak. Uzaktaki bilgisayar kullanıcısı ekranda gördüğü görüntüde istediği nokta(lar) üzerine tıklayarak o noktaların koordinatlarını araca ağ üzerinden gönderecektir. Server a gelen koordinatlar görüntüde meydana gelen kaymalara göre görüntüyü ilk konumuna getirmek üzere server tarafından servo motorlar sürdürülmektedir. Bu bahsettiğim işlemleri gerçekleştiren önemli kısımları ve sever-client tarafının çalışan kodların tamamı aşağıda sizlere sunulmuştur.

 

 

if(trackStart)
								{
									if(originX - avX >= sensitivity)
									{
										 Port_Write(&d,1);
										printf("sol\n");
										tmp=1;
									}
									else if( avX - originX >= sensitivity)
									{
										Port_Write(&a,1);
										printf("sag\n");
										tmp=1;
									}
									if(originY - avY >= sensitivity)
									{
										Port_Write(&w,1);
										printf("yukarı\n");
										tmp=1;
									}
									else if(avY - originY >= sensitivity)
									{
										Port_Write(&s,1);
										printf("asagi\n");
										tmp=1;
									}
									if(tmp!=1)
									//	printf("OK\n");
						     			tmp=0;
								}

 

server programımız ilk açılışta kamera servoları+ gps dataları ve magnetometre datalarını kontrol eden stellaris işlemci ile haberleşmek için bir seri port oluşturmaktadır. Eğer seçili bir nokta yok ise program takip işlemini gerçekleştirmemektedir. Takip için bir nokta gelmiş ise ve sonraki frame lerde o noktanın hareketi bizim önceden belirlediğimiz sensitivity değerinden büyük ise, oluşturduğumuz seri port üzerinden alt işlemcimize kamerayı yukarı, aşağı,sağ,sol (w,a,s,d) hareket komutları server tarafından gönderilmektedir.

if (is_data_ready) {
			bytes = send(clientsock, img1->imageData, imgsize, 0);
			////////////////////////////////////////////////
					bytes2=recv(clientsock,nokta_var,1,0);
					if(nokta_var[0]=='1'){
						bytes2=recv(clientsock,datas,6,0);
						//printf("dataaaaaaaa = %s",datas);
						point.x= x_point;
						point.y=y_point;
						x_point=100*datas[0]+10*datas[1]+datas[2];
						y_point=100*datas[3]+10*datas[4]+datas[5];
						add_point = 1;
 
						printf("x degeri: %d    y degeri:%d\n",x_point,y_point);
					}
			/////////////////////////////////////////////////////////
			is_data_ready = 0;
		}

görüntü takip ve iletimi kısmında çalışan bir main birde thrad vardır. mainde frame yapısı kameradan alınır ve görüntü gri tonuna dönüştürülerek tek boyutlu byte array elde edilir. sonrasında gönderme işlemi için thread çalışır ve send() fonksiyonu ile bütün array gönderilir. Hemen ardından da uzaktaki bilgisayardan nokta olup olmadığı beklenir. Eğer var ise koordinatlar alınır ve nokta yerleştirilir, eğer yok ise direk maine iş devredilir.

#include <fcntl.h>
#include <termios.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "cv.h"
#include "highgui.h"
 
///////// bench
#include <ctime>
#include <iostream>
 
time_t start, end;
double fps;
int counterr = 0;
double sec;
 
/// bench son
 
#define PORT 5001
int sensitivity= 10;
int tmp=0;
int trackStart=0;
int need_to_init=0;
int reset=0;
int avX,avY,originX,originY;
int ysum,xsum;
CvCapture*	capture;
IplImage*	img0;
IplImage*	img1;
IplImage*	img2;
int			is_data_ready = 0;
int			serversock, clientsock;
 
char a='a';
char s='s';
char d='d';
char w='w';
 
IplImage* eig;
IplImage* temp;
double quality;
double min_distance;
////////////////
CvPoint point;
int add_point=0;
//CvCapture *capture;
IplImage* tmp_frame;
CvPoint2D32f *points_32f[2] = {0,0};
CvPoint2D32f *temp_points;
int counter = 0;
char* status = 0;
int flags;
 
IplImage *image = 0,
		 *grey = 0,
		 *prev_grey = 0,
		 *pyramid = 0,
		 *prev_pyramid = 0,
		 *swap_temp;
int Port_Dosya;
int tmp_val=0;
 
void create_circle();
void init_features();
void init_features();
void get_features();
void start_track();
void save_old_frames();
struct termios ayar;
 
int PortAc(void) /*PortAc adıyla bir prosedur Tanımladık */
{
 
	Port_Dosya  =  open("/dev/ttyUSB0", O_RDWR| O_NOCTTY | O_NDELAY);
 
	if (Port_Dosya == -1) /* Eğer Portumuz açılamadıysa */
	{
	//	perror ("PortAc: /dev/ttyS0 aygıtı işletilemiyor");
	}
	else
		fcntl(Port_Dosya,F_SETFL,0);
	return (Port_Dosya);
}
 
void Port_Write(char *wrt,int i)
{
	int yaz; /* integer olarak yaz değişkenimizi tanımladık */
 
	yaz=write(Port_Dosya, wrt,i);
 
	if (yaz<0) /* yazın dönüş değeri 0 dan küçükse */
		fputs("Porta Bilgi yazılamıyor\n",stderr);
}
 
///////////////////
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
void* streamServer(void* arg);
void  quit(char* msg, int retval);
 
void Convert()
{
	img2 = cvQueryFrame(capture);
	CvSize size = cvGetSize(img2);
 
	//size.height = size.height/4;
	//size.width /=4;
 
	img0 = cvCreateImage(size,img2->depth,img2->nChannels);
 
	cvResize(img2,img0);
	//cvShowImage("LOO",img0);
	//char c=0;
	//c=cvWaitKey(33);
 
}
 
int main(int argc, char** argv)
{
	pthread_t 	thread_s;
	char		key;
 
	/////////////////////////////////////////////
 
		    ayar.c_cflag &= ~PARENB;
			ayar.c_cflag &= ~CSTOPB;
			ayar.c_cflag &= ~CSIZE;
			ayar.c_cflag |= CS8;
			ayar.c_cflag &= ~CSIZE; /* karakter uzunluk bit maskesi */
			ayar.c_cflag |= CS8; /* sekiz karakteri paketle */
			ayar.c_cflag |= (CLOCAL | CREAD);
			Port_Dosya = PortAc();
			tcgetattr(Port_Dosya, &ayar);
			cfsetispeed(&ayar, B115200);
			cfsetospeed(&ayar, B115200);
			tcsetattr(Port_Dosya, TCSANOW, &ayar);
	//////////////////////////////////////////////////
 
	capture = cvCaptureFromCAM(1);
	Convert();
 
	img1 = cvCreateImage(cvGetSize(img0), IPL_DEPTH_8U, 1);
 
	cvZero(img1);
	printf( "width:  %d\nheight: %d\n\n", img0->width, img0->height);
 
	/* run the streaming server as a separate thread */
	if (pthread_create(&thread_s, NULL, streamServer, NULL)) {
		quit("pthread_create failed.", 1);
	}
	time(&start);
	while(key != 'q') {
////////////////////  görüntü bench////
		time(&end);
		++counterr;
		sec = difftime (end, start);
		fps = counterr / sec;
		printf("fps = %.2f\n", fps);
////////////  görüntü bench son //////////////
 
		/* get a frame from camera */
 
		//img0 = cvQueryFrame(capture);
		Convert();
		if (!img0) break;
 
		//img0->origin = 0;
		//cvFlip(img0, img0, -1);
		///////////////////////////////////////////
		if(!image)
			init_features();
		cvCopy( img0, image, 0 );
		cvCvtColor( image, grey, CV_BGR2GRAY );
		if(reset)
				{
				cvReleaseImage( &image );
				counter=0;
				reset=0;
				trackStart=0;
				need_to_init=0;
 
				}
		else if( need_to_init)
				{
					sensitivity=75;
					eig = cvCreateImage( cvGetSize(grey), 32, 1 );
					temp = cvCreateImage( cvGetSize(grey), 32, 1 );
					quality = 0.01;
					min_distance = 10;
		            counter = 500;
		            cvGoodFeaturesToTrack( grey, eig, temp, points_32f[1], &counter,quality, min_distance, 0, 3, 0, 0.04 );
		            cvFindCornerSubPix( grey, points_32f[1], counter,cvSize(CV_WINDOW_AUTOSIZE,CV_WINDOW_AUTOSIZE), cvSize(-1,-1),
		            cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
		            cvReleaseImage( &eig );
		            cvReleaseImage( &temp );
			        need_to_init=0;
				}
		else if(counter){
 
					need_to_init=0;
								start_track();
								xsum=0;
								ysum=0;
								create_circle();
								avX = 2*xsum/counter;
								avY = 2*ysum/counter;
 
								if(trackStart)
								{
									if(originX - avX >= sensitivity)
									{
										 Port_Write(&d,1);
										printf("sol\n");
										tmp=1;
									}
									else if( avX - originX >= sensitivity)
									{
										Port_Write(&a,1);
										printf("sag\n");
										tmp=1;
									}
									if(originY - avY >= sensitivity)
									{
										Port_Write(&w,1);
										printf("yukarı\n");
										tmp=1;
									}
									else if(avY - originY >= sensitivity)
									{
										Port_Write(&s,1);
										printf("asagi\n");
										tmp=1;
									}
									if(tmp!=1)
									//	printf("OK\n");
						     			tmp=0;
								}
						}
						if(add_point){
							counter++;
							get_features();
							add_point = 0;
						}
						save_old_frames();
 
		//////////////////////////////////////////
 
		pthread_mutex_lock(&mutex);
		cvCvtColor(img0, img1, CV_BGR2GRAY);
		is_data_ready = 1;
		pthread_mutex_unlock(&mutex);
 
		////////////////////////// takip kısmı /////////////////////////////
 
		///////////////////////// takip kısmı son//////////////////////////
 
	cvShowImage("stream_server", image);
 
		key = cvWaitKey(10);
 
				if(key== 'r')
				{
					reset=1;
 
				}
 
				else if(key=='i')
					need_to_init=1;
				else if(key=='t')
				{
					trackStart=1;
					originX =avX;
					originY =avY;
				}
	}
 
	/* user has pressed 'q', terminate the streaming server */
	if (pthread_cancel(thread_s)) {
		quit("pthread_cancel failed.", 1);
	}
 
	/* free memory */
	//cvDestroyWindow("stream_server");
	quit(NULL, 0);
}
 
/**
 * This is the streaming server, run as a separate thread
 * This function waits for a client to connect, and send the grayscaled images
 */
void* streamServer(void* arg)
{
	int bytes2,x_point,y_point;
	char nokta_var[1],datas[6];
	struct sockaddr_in server;
 
	/* make this thread cancellable using pthread_cancel() */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
	/* open socket */
	if ((serversock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
		quit("socket() failed", 1);
	}
 
	/* setup server's IP and port */
	memset(&server, 0, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = INADDR_ANY;
 
	/* bind the socket */
	if (bind(serversock, (struct sockaddr *)&server, sizeof(sockaddr)) == -1) {
		quit("bind() failed", 1);
	}
 
	/* wait for connection */
	if (listen(serversock, 10) == -1) {
		quit("listen() failed.", 1);
	}
 
	/* accept a client */
	if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
		quit("accept() failed", 1);
	}
 
	/* the size of the data to be sent */
	int imgsize = img1->imageSize;
	int bytes;
 
	/* start sending images */
	while(1)
	{
		/* send the grayscaled frame, thread safe */
		pthread_mutex_lock(&mutex);
		if (is_data_ready) {
			bytes = send(clientsock, img1->imageData, imgsize, 0);
			////////////////////////////////////////////////
					bytes2=recv(clientsock,nokta_var,1,0);
					if(nokta_var[0]=='1'){
						bytes2=recv(clientsock,datas,6,0);
						//printf("dataaaaaaaa = %s",datas);
						point.x= x_point;
						point.y=y_point;
						x_point=100*datas[0]+10*datas[1]+datas[2];
						y_point=100*datas[3]+10*datas[4]+datas[5];
						add_point = 1;
 
						printf("x degeri: %d    y degeri:%d\n",x_point,y_point);
					}
			/////////////////////////////////////////////////////////
			is_data_ready = 0;
		}
 
		pthread_mutex_unlock(&mutex);
 
		/* if something went wrong, restart the connection */
		if (bytes != imgsize) {
			fprintf(stderr, "Connection closed.\n");
			close(clientsock);
 
			if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
				quit("accept() failed", 1);
			}
		}
 
		/* have we terminated yet? */
		pthread_testcancel();
 
		/* no, take a rest for a while */
		usleep(1000);
	}
}
//////////////////////////////////////////////////////////////////////////////
///////////////////////takip fonksiyonları////////////////////////////////////
void create_circle()
{
	//printf("it is in create_circle function\n");
	int i=0,k=0;
	for(;i< counter; i++){
		if( !status[i] )
			continue;
		points_32f[1][k++] = points_32f[1][i];
		cvCircle(image, cvPointFrom32f(points_32f[1][i]), 3, CV_RGB(255,0,0), -1, 8,0);
		xsum+=points_32f[1][i].x;
				ysum+=points_32f[1][i].y;
	}
}
void show_camera(){
	//printf("it is in show_camera function\n");
	//cvShowImage( "Test", image );
	char c = cvWaitKey(3);
	if(c== 27)exit(0);
 
}
void init_features(){
	//printf("it is in init_features function\n");
	 image = cvCreateImage( cvGetSize(img0), 8, 3 );
	 image->origin = img0->origin;
	 grey = cvCreateImage( cvGetSize(img0), 8, 1 );
	 prev_grey = cvCreateImage( cvGetSize(img0), 8, 1 );
	 pyramid = cvCreateImage( cvGetSize(img0), 8, 1);
	 prev_pyramid = cvCreateImage( cvGetSize(img0), 8, 1 );
	 flags = 0; //flag for track accomplished
     status = (char*)cvAlloc(500);
     points_32f[0] = (CvPoint2D32f*)cvAlloc(500*sizeof(points_32f[0][0]));
     points_32f[1] = (CvPoint2D32f*)cvAlloc(500*sizeof(points_32f[0][0]));
}
 
void get_features(){
	//printf("it is in get features function\n");
    points_32f[1][counter-1] = cvPointTo32f(point);
    cvFindCornerSubPix(
                		grey,
                		points_32f[1]+counter-1,
                		1,
                		cvSize(15,15),
                		cvSize(-1,-1),
                		cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)
                );
 
}
void start_track(){
	//printf("it is in start_track function\n");
	cvCalcOpticalFlowPyrLK(
	        			prev_grey,
	        			grey,
	        			prev_pyramid,
	        			pyramid,
	        			points_32f[0],//prev one
	        			points_32f[1],//current one
	        			counter,
	        			cvSize(15,15),
	        			3,
	        			status,
	        			0,
	        			cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03),
	        			flags
	        	);
	//flags |= CV_LKFLOW_PYR_A_READY;
 
}
void save_old_frames(){
	CV_SWAP( prev_grey, grey, swap_temp );
	CV_SWAP( prev_pyramid, pyramid, swap_temp );
	CV_SWAP( points_32f[0], points_32f[1], temp_points );
}
 
//////////////////////////////////////////////////////////////////////////////
 
/**
 * this function provides a way to exit nicely from the system
 */
void quit(char* msg, int retval)
{
	if (retval == 0) {
		fprintf(stdout, (msg == NULL ? "" : msg));
		fprintf(stdout, "\n");
	} else {
		fprintf(stderr, (msg == NULL ? "" : msg));
		fprintf(stderr, "\n");
	}
 
	if (clientsock) close(clientsock);
	if (serversock) close(serversock);
	if (capture) cvReleaseCapture(&capture);
	if (img1) cvReleaseImage(&img1);
 
	pthread_mutex_destroy(&mutex);
 
	exit(retval);
}

 

Client tarafında ise gönderdiğimiz frame nin boyutu kadar data yakalanır, sonrasında ise bu datalardan ipimage formatı doldurulur ve gönderdiğimiz frame tekrar elde edilir.  Eğer camera_on_mouse() fonksiyonu ile bir koordinat yakalanmamışsa direk nokta yok bilgisi server a iletilir. Eğer bir nokta koordinatı varsa önce nokta olduğu iletilip server ın koordinatları beklemesi sağlanılır ve noktalar gönderlir.

 

for (i = 0; i < imgsize; i += bytes) {
			if ((bytes = recv(sock, sockdata + i, imgsize - i, 0)) == -1) {
				quit("recv failed", 1);
			}
		}
 
		/* convert the received data to OpenCV's IplImage format, thread safe */
		pthread_mutex_lock(&mutex);
 
		for (i = 0, k = 0; i < img->height; i++) {
			for (j = 0; j < img->width; j++) {
				((uchar*)(img->imageData + i * img->widthStep))[j] = sockdata[k++];
			}
		}
 
		bytes2 = send(sock, nokta_var, 1, 0);
		if(nokta_var[0]!='0'){
				if(nokta_var[0]=='1'){
						datas[0]=char(point.x/100);
						datas[1]=char((point.x%100)/10);
						datas[2]=char(point.x%10);
						datas[3]=char(point.y/100);
						datas[4]=char((point.y%100)/10);
						datas[5]=char(point.y%10);
						bytes2 = send(sock, datas,6, 0);
 
			}
 
			nokta_var[0]='0';
		}

 

server ve client tarafının video aktarımı ve nesne takibi kısımlarının önemli parçalarını açıklamaya çalıştım. Geri kalan kısımları önceki paylaşımlarda açıklamaya çalıştığım soket oluşturma ve veri gönderme algoritmalarının aynısıdır.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "cv.h"
#include "highgui.h"
 
IplImage* img;
int 	  is_data_ready = 0;
int 	  sock;
char* 	  server_ip="192.168.1.3";
int 	  server_port=5001;
char nokta_var[1];
CvPoint point;
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
void* streamClient(void* arg);
void  quit(char* msg, int retval);
void camera_on_mouse( int event, int x, int y, int flags, void* param );
 
int main(int argc, char** argv)
{
	pthread_t thread_c;
	int	width, height, key;
	// çerçeve boyutlarını server tarafındaki kameranınkine göre ayarla
	//width		= 640/4;
	//height		= 480/4;
	width		= 640;
	height		= 480;
	/* create image */
	img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
	cvZero(img);
 
	/* run the streaming client as a separate thread */
	if (pthread_create(&thread_c, NULL, streamClient, NULL)) {
		quit("pthread_create failed.", 1);
	}
 
	fprintf(stdout, "Press 'q' to quit.\n\n");
	cvNamedWindow("received_video", CV_WINDOW_NORMAL);
	cvSetMouseCallback( "received_video", camera_on_mouse, 0 );
 
	while(key != 'q') {
		/**
		 * Display the received image, make it thread safe
		 * by enclosing it using pthread_mutex_lock
		 */
		pthread_mutex_lock(&mutex);
		if (is_data_ready) { // bir frame in bütün dataları gelmiş ise
			cvShowImage("received_video", img);
			is_data_ready = 0;
		}
		pthread_mutex_unlock(&mutex);
 
		key = cvWaitKey(10);
	}
 
	/* user has pressed 'q', terminate the streaming client */
	if (pthread_cancel(thread_c)) {
		quit("pthread_cancel failed.", 1);
	}
 
	/* free memory */
	cvDestroyWindow("received_video");
	quit(NULL, 0);
}
 
/**
 * This is the streaming client, run as separate thread
 */
void* streamClient(void* arg)
{
	struct 	sockaddr_in server;
 
	/* make this thread cancellable using pthread_cancel() */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
	/* create socket */
	if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
		quit("socket() failed.", 1);
	}
 
	/* setup server parameters */
	memset(&server, 0, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(server_ip);
	server.sin_port = htons(server_port);
 
	/* connect to server */
	if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
		quit("connect() failed.", 1);
	}
 
	int  imgsize = img->imageSize;
	char sockdata[imgsize],datas[6];
	int  i, j, k, bytes,bytes2;
 
	/* start receiving images */
	while(1)
	{
		/* get raw data */
		for (i = 0; i < imgsize; i += bytes) {
			if ((bytes = recv(sock, sockdata + i, imgsize - i, 0)) == -1) {
				quit("recv failed", 1);
			}
		}
 
		/* convert the received data to OpenCV's IplImage format, thread safe */
		pthread_mutex_lock(&mutex);
 
		for (i = 0, k = 0; i < img->height; i++) {
			for (j = 0; j < img->width; j++) {
				((uchar*)(img->imageData + i * img->widthStep))[j] = sockdata[k++];
			}
		}
 
		bytes2 = send(sock, nokta_var, 1, 0);
		if(nokta_var[0]!='0'){
				if(nokta_var[0]=='1'){
						datas[0]=char(point.x/100);
						datas[1]=char((point.x%100)/10);
						datas[2]=char(point.x%10);
						datas[3]=char(point.y/100);
						datas[4]=char((point.y%100)/10);
						datas[5]=char(point.y%10);
						bytes2 = send(sock, datas,6, 0);
 
			}
 
			nokta_var[0]='0';
		}
 
		is_data_ready = 1;
		pthread_mutex_unlock(&mutex);
 
		/* have we terminated yet? */
		pthread_testcancel();
 
		/* no, take a rest for a while */
		usleep(1000);
	}
}
 
void camera_on_mouse( int event, int x, int y, int flags, void* param ){
 
	if( event == CV_EVENT_LBUTTONDOWN )
	    {
		//printf("it is in camera on mouse function\n");
			point = cvPoint(x,y);
			printf("x noktasi : %d     y noktasi: %d\n",point.x,point.y);
	        nokta_var[0] = '1';
	    }
 
}
 
/**
 * This function provides a way to exit nicely from the system
 */
void quit(char* msg, int retval)
{
	if (retval == 0) {
		fprintf(stdout, (msg == NULL ? "" : msg));
		fprintf(stdout, "\n");
	} else {
		fprintf(stderr, (msg == NULL ? "" : msg));
		fprintf(stderr, "\n");
	}
 
	if (sock) close(sock);
	if (img) cvReleaseImage(&img);
 
	pthread_mutex_destroy(&mutex);
 
	exit(retval);
}

 

tcp video serverdan seri port ile stellaris e gönderilen servo hareket komutları  stellariste uart interrupt handler fonksiyonu tarafından yakalanıp istenilen servonun açısı hassasiyet değerine göre arttırılıp azaltılmaktadır.

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_i2c.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "utils/uartstdio.h"
#include "driverlib/debug.h"
#include "utils/ustdlib.h"
#include "driverlib/uart.h"
#include "inc/hw_ints.h"
#include "driverlib/pwm.h"
 
#include <string.h>
 
#define NUM_I2C_DATA 4
#define SLAVE_ADDRESS 0x0E
int counter =0;
volatile char temp[2000];
unsigned long ulStatus;
int GGA=0;
int valid=0;
volatile char data[90];
int bit =0;
 
unsigned long ulPeriod2;
float center_up=102;
float center_down=74;
float up_sens=0.40;
float down_sens=0.40;
unsigned short bearing=0;
char old[2];
char new1[2];
char datam[4];
 
void
init_mcu()
{
 
	Display96x16x1Init(false);//LCD ekran
 
	//
    // 	  Osilatör ayarı
    // 
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);
 
	//
    // I2C0 çevresel aygıtını enable yap
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
 
    //
    // I2C PortB[3:2] pinleri üzerinde
    // 
 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
 
    //
    // Master Modülü tanımla 
	// En sağdaki parametre false olursa 100kbps true olursa 400kbps hızında data rate oluyoe
    //
    I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);
 
	///////////////////////
	  SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);    
 
    ulPeriod2 = SysCtlClockGet() /50; // servo period
 
    PWMGenConfigure(PWM_BASE, PWM_GEN_0,
                    PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
 
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, ulPeriod2);//  motor
 
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, ulPeriod2 * center_up / 1000);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, ulPeriod2 * center_down / 1000);  	  
 
    PWMGenEnable(PWM_BASE, PWM_GEN_0);	
 
	PWMOutputState(PWM_BASE, PWM_OUT_1_BIT , true);
	PWMOutputState(PWM_BASE, PWM_OUT_0_BIT, true);
    //////////////
 
}
 
void
InitConsole(void)  //115200n8 
{
    //
    // UART0 PortA[1:0] kullanıldığı için bu çevresel aygıtı ENABLE yapıyoruz  
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 
    //
    // Konsol I/O için UART tanımlaması yap
    //
    UARTStdioInit(0);
 
}
 
void UART0IntHandler(void)
{		
    unsigned long ulStatus;
	char  temp[1]; 
 
	// UARTprintf("girdiiiiii");
 
    ulStatus = UARTIntStatus(UART0_BASE, true);   
 
    temp[0] = UARTCharGet(UART0_BASE);
 
    switch (temp[0])
    {
    	case 'w' :
    		center_up-=up_sens;
    		PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, ulPeriod2 * center_up / 1000);
 
    		break;	
    	case 's' :
    		center_up+=up_sens;
    		PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, ulPeriod2 * center_up / 1000);
 
    		break;
    	case 'd' :
    		center_down+=down_sens;
    		PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, ulPeriod2 * center_down / 1000);   	
 
    		break;
    	case 'a' :
    		center_down-=down_sens;
    		PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, ulPeriod2 * center_down / 1000);   
 
    		break;
    	case ' ' :
 
    		break;
 
    }	
	UARTIntClear(UART0_BASE, ulStatus);		// seri port interrupt bayrağını temizler  
}
 
Read()
{
 
	//Read();
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x42 >> 1, false);
 
    I2CMasterDataPut(I2C0_MASTER_BASE, 'A');
 
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
 
    while(I2CMasterBusy(I2C0_MASTER_BASE));
 
	//	SysCtlDelay(SysCtlClockGet() / 3000);						   //delay
		//DELAY
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x42 >> 1, true);
 
    I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
 
    while(I2CMasterBusy(I2C0_MASTER_BASE));
 
    bearing = ((char) I2CMasterDataGet(I2C0_MASTER_BASE)) << 8;
 
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
 
    while(I2CMasterBusy(I2C0_MASTER_BASE));
 
    bearing |= (char) I2CMasterDataGet(I2C0_MASTER_BASE);
 
		SysCtlDelay(SysCtlClockGet() / 3000);
   // UARTprintf("Received: '%d'\n\n", bearing);
	//	SysCtlDelay(SysCtlClockGet() / 100);						   //delay
 
		if((bearing>= 230) && (bearing < 680))
		{	new1[0] = 'K'; new1[1] = 'D';}
		else if((bearing>= 680) && (bearing <1130))
		{	new1[0] = 'D'; new1[1] = 'O';}
		else if((bearing>=1130) && (bearing <1580))
		{	new1[0] = 'G'; new1[1] = 'D';}
		else if((bearing>=1580) && (bearing <2030))
		{new1[0] = 'G'; new1[1] = 'U';}
		else if((bearing>=2030) && (bearing <2480))
		{	new1[0] = 'G'; new1[1] = 'B';}
		else if((bearing>=2480) && (bearing <2930))
		{	new1[0] = 'B'; new1[1] = 'A';	}	
		else if((bearing>=2930) && (bearing <3380))
		{	new1[0] = 'K'; new1[1] = 'B';}
		else if(  ((bearing>= 3380) &&(bearing<3600)) || ((bearing>=0) && (bearing<230) )  )
		{	new1[0] = 'K'; new1[1] = 'U';}
		//UARTprintf("Y%s",new1);
		if((new1[0] != old[0]) || (new1[1] != old[1]))
		{
		old[0] = new1[0];
		old[1] = new1[1];
		}	
 
}
 
void
ConfigInt()
{
	 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
	 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	 IntMasterEnable();
	 GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3);
 
	 UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 9600,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));
	 IntEnable(INT_UART1);
	 UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);
	IntEnable(INT_UART0);
	 UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
 
}
 
void 
getLocation(char * pch)
{
	 pch = strtok (data,",");
 
	 while (pch != NULL)
  	 {
 
		if(GGA==6)
		{
		   //if(*pch=='E')
		//		UARTprintf(" Dogu\n");
		 //  else if(*pch=='W')
		//		UARTprintf(" Bati\n");
		   UARTprintf("%c%c",old[0],old[1]);
		   GGA=0;
		   //UARTprintf("\n");
		}
		else if(GGA==5)
		{
		   UARTprintf("B%s",pch);
		   GGA=6;
		}
		else if(GGA==4)
		{
			GGA=5;
			//if(*pch=='N')
			//	UARTprintf(" K\n");
			//else if(*pch=='S')
			//	UARTprintf(" G\n");
		}
		else if(GGA==3)
		{
			UARTprintf("X");
			UARTprintf("E%s",pch);
			GGA=4;
		}	
		else if(GGA==2)
		{
			GGA=3;
		   	//UARTprintf("UTC zamani= %s\n",pch);
 
		}
		else if(GGA==1)
		{
			GGA=2;
		}
		pch = strtok (NULL,",");
	 }
}
 
void
UARTIntHandler(void)
{	 
	 static int i=0;
	 static int j=0;
 
	 ulStatus = UARTIntStatus(UART1_BASE, true); 
 
	  while(UARTCharsAvail(UART1_BASE))
	  {
        temp[i] =  UARTCharGetNonBlocking(UART1_BASE); 
	//	UARTprintf("UART1 INT");	
	//	UARTprintf("%s\n",temp);	
		if(i>=5 && temp[i]=='A' && temp[i-1]=='G' && temp[i-2]=='G' && temp[i-3]=='P'&& temp[i-4]=='G'&& temp[i-5]=='$')
		{
 
			for(j=0;j<6;j++)
				data[j] = temp[i+j-5];
 
			valid = 1 ;
			GGA=1;
		}
 
	    if(valid == 1 )
	    {
 
			data[j] = temp[i];
 
			if(temp[i]=='*')
	 		{
			  valid=0;
			  //UARTprintf("%s\n",data);		 
			  getLocation(data);
 
			}
		} 
 
	j=(j+1)%2000;
	i=(i+1)%2000;
 
	}
 
	UARTIntClear(UART1_BASE, ulStatus);		// seri port interrupt bayrağını temizler 
}
 
int
main(void)
{
 
	//
	// MCU ayarlarını yap 
	//
	init_mcu ();  
 
	Display96x16x1StringDraw("start", 0, 0);
	//
	// UART ayarlarını yap
	//
	InitConsole();
	ConfigInt();
	Display96x16x1StringDraw("start", 0, 0);
	//UARTprintf(" deneme \n");
	while(1)
	{
		Read();
	}
	UARTprintf("\nIs lem Tamamlandi.\n\n");
 
	return(0);
 
}