Tile detection algorithm on linux platform


After the success of using opencv to determine tile locations, we proceed to move the code to linux. 

As the opencv is multi-platform supported, there is not many modification during the conversion, but several aspects are different.


Installation is quite different:

sudo apt-get install opencv-doc libcv4 libhighgui4 libcvaux4 libcv-dev libcvaux-dev libhighgui-dev libgtk2.0-dev
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg62-dev libtiff4-dev cmake libswscale-dev libjasper-dev
sudo apt-get install libopencv-dev

compiling operations on linux using opencv

gcc main.cpp -o main -ggdb `pkg-config opencv --cflags --libs` -lm  -lstdc++


compiling operations on linux using opencv and serial communication

gcc -ggdb `pkg-config opencv --cflags --libs` det.cpp rs232.cpp -o det -lm  -lstdc++


Besides, we add new features in the end of program. Data collected should be able to send to robot arm. We added the coomunication part, either by serial communication or TCP package.


Sample pictures:

blob.png

Codes:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

//socket
//windows
//#include <WinSock2.h>
//linux
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//end socket

#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
// #include <opencv2/opencv_modules.hpp>

using namespace cv;
using namespace std;

/**************Definitons*************/
#define MAXRECT				100
#define BUF_SIZE			1024
#define SERVER_ADDRESS		"192.168.0.102"
#define LISTEN_PORT			2000
#define ID					"50-0503334900"
#define THRESH				100
#define AREALIMIT			3000.0
/**************Variables**************/

vector<RotatedRect>		rectProfile;
vector< vector<Point> >	contoursRect;
vector< vector<Point> >	contours;
vector<int> selected;

struct sockaddr_in serveraddr;
char recvbuf[BUF_SIZE]={0};
char sendbuf[BUF_SIZE]={0}; 
int sockfd;

char buf[BUF_SIZE];

/**************Functions**************/
bool Init();
bool CameraInit();
bool SocketInit();
void SocketFinish();
void SendPackage();

bool Init(){
	if (CameraInit()) 
		printf("Camera Init Fail.\n"); 
	else
		printf("Camera Init Success.\n");
	if (SocketInit()) 
		printf("Socket Init Fail.\n"); 
	else
		printf("Socket Init Success.\n");
	return 0;
}

bool CameraInit(){
	return 0;
}

bool SocketInit(){
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;//标明通讯协议为TCP
	serveraddr.sin_port = htons(LISTEN_PORT);//服务端端口
	serveraddr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);//服务端IP地址。 
	sockfd = socket(AF_INET, SOCK_STREAM, 0);// 创建一个用于通信的sockfd 
	if(sockfd == -1)
	{
	perror("socket");
	return 1;
	} 
	int ret = connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr));//链接服务端 
	if(ret == -1)
	{
	perror("connect");
	return 1;
	}
	//bzero(sendbuf, BUF_SIZE);
	//strcat(sendbuf, "Start..\n");
	//send(sockfd, sendbuf, strlen(sendbuf),MSG_DONTWAIT); 
	return 0;
}

void SendPackage(){
	bzero(sendbuf, BUF_SIZE);
	strcat(sendbuf, "Image\n");

	for (int i = 0; i < rectProfile.size(); i++){
		char tmpString[100];
		sprintf(tmpString, "[X:%.4f;Y:%.4f;A:%.4f;]\n", rectProfile[i].center.x, rectProfile[i].center.y, rectProfile[i].angle);
		strcat(sendbuf, tmpString);
		//printf(buf);
	}
	strcat(sendbuf, "Done\n");
	printf(sendbuf);
	send(sockfd, sendbuf, strlen(sendbuf)+1,MSG_DONTWAIT); 
	memset(recvbuf, 0, sizeof(recvbuf));
	recv(sockfd,recvbuf,sizeof(recvbuf),MSG_DONTWAIT);
 	printf("recv=%s\n", recvbuf);
}

bool Check(vector<Point> con){
	//printf("%d\n", con.size());
	double area = abs(contourArea(con, 1));
	printf("%lf\n", area);
	if (area < AREALIMIT) return false;
	return true;
	RotatedRect profile = minAreaRect(con);
	double len = profile.size.height;
	double wid = profile.size.width;
	if (len < wid) swap(len, wid);
	if (len / wid > 4.0)
		return false;
	if (len / wid < 1.5)
		return false;
	return true;
}

void SocketFinish(){
}

void ImageProcess(){
	Mat img = imread("sample00012_5.jpg", CV_LOAD_IMAGE_GRAYSCALE);

	Mat imgCanny;
	Canny(img, imgCanny, THRESH, THRESH * 2);
	//imshow("1.Canny", imgCanny);
	imwrite("tile/1.Canny.jpg",imgCanny);

	findContours(imgCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	Mat cc = Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	for (int j = 0; j < contours.size(); j++){
		Scalar color(rand()&255, rand()&255, rand()&255);
		drawContours(cc, contours, j, color);
	}
	//imshow("2.Contours", cc);
	imwrite("tile/2.Contours.jpg",cc);

	int n = 0;
	contoursRect.clear();
	for (unsigned int i = 0; i < contours.size(); i++){
		if (Check(contours[i])){
			contoursRect.push_back(contours[i]);
			n++;
		}
	}
	printf("%d\n", n);

	Mat ccc = Mat::zeros(imgCanny.rows, imgCanny.cols, CV_8UC3);
	for (int i = 0; i < n; i++){
		Scalar color(rand()&255, rand()&255, rand()&255);
		drawContours(ccc, contoursRect, i, color);
	}
	//imshow("3.Contourchecked", ccc);
	imwrite("tile/3.Contourchecked.jpg",ccc);
	//waitKey();
	//destroyAllWindows();
	rectProfile.clear();
	for (int i = 0; i < n; i++) {
		rectProfile.push_back(minAreaRect(contoursRect[i]));
	}
}

int main(){
	Init();
	contours.reserve(100000*sizeof(Point));
	ImageProcess();
	SendPackage();
	SocketFinish();
}


This article is among the series of FDUROP project. More information: http://104.131.150.53/thinkcmfx/index.php?g=&m=article&a=index&id=17


Last Article Next article

Comment 评论



Share 分享

New Users 最新加入

  • hokurikustr

  • refrain

New comments 最新评论

test123: aasdas Details Apr 13 16:39
admin: Thanks! Details Apr 09 11:46
admin: Google map api Details Apr 09 11:46
lqj12: cooooooooool Details Apr 08 21:34
Yunhan Huang: 这个功能是如何实现的? Details Apr 08 13:23