int openHand(PointCloud handPcl) { IplImage *imageHandBw = cvCreateImage(cvSize(640,480), 8, 1); binaryImage(handPcl, imageHandBw); cvDilate(imageHandBw, imageHandBw, NULL, 5); cvErode(imageHandBw, imageHandBw, NULL, 3); int perimeter = 0, area = 0; int i; for (i=0; i<FREENECT_FRAME_PIX; i++) { if(((unsigned char*)(imageHandBw->imageData))[i]) { area++; if (((unsigned char*)(imageHandBw->imageData))[i+1] == 0 || ((unsigned char*)(imageHandBw->imageData))[i-1] == 0 || ((unsigned char*)(imageHandBw->imageData))[i+FREENECT_FRAME_W] == 0 || ((unsigned char*)(imageHandBw->imageData))[i-FREENECT_FRAME_W] == 0) perimeter++; } } formFactor= 4 * M_PI * area / (perimeter * perimeter); //printf("PointCount: %d - Perimeter: %d - FF: %f\n", area, perimeter, formFactor); // cvShowImage("Depth", imageHandBw); cvReleaseImage(&imageHandBw); return (formFactor < OPEN_HAND_FORM_FACTOR); }
vector<int> threshold(vector<int> image) { vector<int> binaryImage(NUM_PIXELS, 0); for(int i=0; i < NUM_PIXELS; i++) binaryImage[i] = (image[i] > 127) ? 1 : 0; return binaryImage; }
void getEndPointOfLine(const Mat src,const vector<electronComponent> DeviceSet,vector<Cline> &circuitLines){ //binary Mat binary; double thre = 10; int mode = CV_THRESH_BINARY_INV; binaryImage(src, binary, thre, mode); //排除元器件,将元器件涂黑 Mat srcB = src.clone(); for(int i = 0;i <DeviceSet.size();i++){ electronComponent DeviceInfo = DeviceSet[i]; vector<vector<Point>> tmp; tmp.push_back(DeviceSet[i].contours); drawContours(srcB, tmp, 0, Scalar(0),CV_FILLED); } //线的细化 Mat bin; int intera = 8; imageThin(binary,bin,intera); //寻找曲线的端点 vector<vector<Point> > contours; Mat copyBin; bin.copyTo(copyBin); findContours(copyBin, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); vector<Cline> lines; for (size_t i = 0; i < contours.size(); i++) { if (contours[i].size() < 10) { continue; } vector<Point> endPoint; findEndPoint(bin,contours[i], endPoint); if (endPoint.size() > 0) { Cline line; line.numPoint = (int)endPoint.size(); for (size_t k = 0;k < endPoint.size();k++) { line.endPoint.push_back(endPoint[k]); } lines.push_back(line); } } //找与线连接的半圆 Mat binaryB = Mat::zeros(srcB.rows, srcB.cols, CV_8UC1); int value1 = 200; int value2 = 20; for (int i = 0; i < srcB.rows; i++) { for (int j = 0; j < srcB.cols; j++) { if (!(srcB.at<Vec3b>(i,j)[0] >= value1 && srcB.at<Vec3b>(i,j)[1] >= value1 &&srcB.at<Vec3b>(i,j)[2] >= value1 ) && !(srcB.at<Vec3b>(i,j)[0] <= value2 && srcB.at<Vec3b>(i,j)[1] <= value2 &&srcB.at<Vec3b>(i,j)[2] <= value2)) { binaryB.at<uchar>(i,j) = 255; } } } medianBlur(binaryB, binaryB, 5); vector<CSemicircle> semicircles; //求半圆的半径 圆心 vector<vector<Point> > contoursb; Mat copyBinaryb = binaryB.clone(); #ifdef _SHOW_ Mat binaryBrgb; cvtColor(binaryB,binaryBrgb, CV_GRAY2BGR); #endif findContours(copyBinaryb, contoursb, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); for (int k = 0; k < contoursb.size(); k++) { CSemicircle semi; float radius; Point2f center; minEnclosingCircle(contoursb[k],center, radius); #ifdef _SHOW_ circle(binaryBrgb, center, radius, Scalar(0,0,255)); #endif semi.center = center; semi.radius = radius; semicircles.push_back(semi); } //连接曲线与半圆 //1 首先将连接的直线连接起来 vector<Cline> newLines; float threRadius = 1.5; for (int i = 0; i < lines.size(); i++) { Cline line; line.numPoint = lines[i].numPoint; for (int j = 0 ; j < lines[i].numPoint; j++ ) { for (int k = 0; k < semicircles.size(); k++) { if (distancePoint(lines[i].endPoint[j], semicircles[k].center) < threRadius * semicircles[k].radius) { line.endPoint.push_back(semicircles[k].center); break; } } } newLines.push_back(line); } #ifdef _SHOW_ Mat rgb2 = src.clone(); for (int i = 0; i < newLines.size(); i++) { for (int j = 0 ; j < newLines[i].numPoint; j++) { circle(rgb2,newLines[i].endPoint[j], 3, Scalar(0,0,255),CV_FILLED); } } imshow("rgb2", rgb2); imshow("ConnectPart",binaryBrgb); waitKey(); std::cout << "newLines: " << newLines.size() << std::endl; #endif //合并 for (int i = 0; i < newLines.size() ; i++) { int flag = 0; for (int j = i+1; j < newLines.size(); j++) { for (int m = 0 ; m < newLines[i].numPoint; m++) { for (int n = 0; n < newLines[j].numPoint; n++) { if (newLines[i].endPoint[m] == newLines[j].endPoint[n]) { vector<Point> newEndPoint; for (int km = 0; km < newLines[i].numPoint; km++) { if (km == m) { continue; } newEndPoint.push_back(newLines[i].endPoint[km]); } for (int kn = 0; kn < newLines[j].numPoint; kn++) { if (kn == n) { continue; } newEndPoint.push_back(newLines[j].endPoint[kn]); } newLines[i].endPoint.clear(); for (int k = 0; k < newEndPoint.size(); k++) { newLines[i].endPoint.push_back(newEndPoint[k]); } newLines[i].numPoint = (int)newLines[i].endPoint.size(); newLines[j].numPoint = 0; newLines[j].endPoint.clear(); flag = 1; break; } } if (flag == 1) { break; } } flag = 0; } } for (int i = 0; i < newLines.size(); i++) { if (newLines[i].numPoint == 0) { continue; } circuitLines.push_back(newLines[i]); } #ifdef _SHOW_ Mat rgb3 = src.clone(); for (int i = 0; i < circuitLines.size(); i++) { for (int j = 0 ; j < circuitLines[i].numPoint; j++) { circle(rgb3,circuitLines[i].endPoint[j], 3, Scalar(0,0,255),CV_FILLED); } imshow("rgb3", rgb3); waitKey(); } std::cout << "circuitLines: " << circuitLines.size() << std::endl; #endif }