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:
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