void getEndPointOfLine(const Mat & src,vector<Cline> & lines){ //二值化 Mat gray; cvtColor(src,gray,CV_BGR2GRAY); Mat binary; double thre = 10; double maxval = 255; threshold(gray, binary, thre, maxval,CV_THRESH_BINARY_INV); medianBlur(binary, binary, 3); //线的细化 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); 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); } } }
/////////////////////////////////////////////////////////////////////////////// // searchDevice() - Search for AOA support device in the all USB devices /////////////////////////////////////////////////////////////////////////////// //argument // ctx : libusb_context // idVendor : return buffer for USB Vendor ID // idProduc : return buffer for USB Product ID // //return // -1 : AOA device not found // 0> : AOA Version // int AOA::searchDevice(libusb_context *ctx, uint16_t *idVendor, uint16_t *idProduct) { int res; int i; libusb_device **devs; libusb_device *dev; struct libusb_device_descriptor desc; ssize_t devcount; *idVendor = *idProduct = 0; res = -1; devcount = libusb_get_device_list(ctx, &devs); if(devcount <= 0){ printf("Get device error.\n"); return -1; } //enumerate USB deivces for(i=0; i<devcount; i++){ dev = devs[i]; libusb_get_device_descriptor(dev, &desc); #ifdef DEBUG printf("VID:%04X, PID:%04X Class:%02X\n", desc.idVendor, desc.idProduct, desc.bDeviceClass); #endif //Ignore non target device if( desc.bDeviceClass != 0 ){ continue; } //Already AOA mode ? if(desc.idVendor == USB_ACCESSORY_VENDOR_ID && (desc.idProduct >= USB_ACCESSORY_PRODUCT_ID && desc.idProduct <= USB_ACCESSORY_AUDIO_ADB_PRODUCT_ID) ){ #ifdef DEBUG printf("already in accessory mode.\n"); #endif res = 0; break; } //Checking the AOA capability. if((handle = libusb_open_device_with_vid_pid(ctx, desc.idVendor, desc.idProduct)) == NULL) { printf("Device open error.\n"); } else { libusb_claim_interface(handle, 0); res = getProtocol(); libusb_release_interface (handle, 0); libusb_close(handle); handle = NULL; if( res != -1 ){ #ifdef DEBUG printf("AOA protocol version: %d\n", verProtocol); #endif break; //AOA found. } } } // find end point number if( findEndPoint(dev) < 0 ){ printf("Endpoint not found.\n"); res = -1; } *idVendor = desc.idVendor; *idProduct = desc.idProduct; #ifdef DEBUG printf("VID:%04X, PID:%04X\n", *idVendor, *idProduct); #endif return res; }
CHandPoint CTransformImage::findFingerInfo() { if(!m_transImage) return CHandPoint(); findCenter(); CHandPoint handPt; std::vector<CvPoint> ptList; double pi = 3.1415; int width = m_transImage->width; int fingerCnt = 0; int x, y, radius = 80; unsigned char ch, pastCh = 0; for(double theta = 180; theta <= 360; ++theta) { x = (int)(m_center.x + radius*cos(theta*pi/180)); y = (int)(m_center.y - radius*sin(theta*pi/180)); ch = m_transImage->imageData[y*width+x]; if(ch == 255 && pastCh == 0) // Counting Finger ptList.push_back(cvPoint(x,y)), ++fingerCnt; pastCh = ch; // Draw OutLine CvBox2D box; box.center = cvPoint2D32f(x, y); box.size = cvSize2D32f(1, 1); box.angle = 90; cvEllipseBox(m_image, box, CV_RGB(255,242,0), 1); } // handPt Setting float dist = 0, dist2 = 0; switch(fingerCnt) { case 0: handPt.m_mode = CHandPoint::CLEAR; break; case 1: handPt.m_mode = CHandPoint::MOVE; findEndPoint(&handPt.m_nX, &handPt.m_nY); break; case 2: { CvPoint a = ptList[0], b = ptList[1]; float dist = sqrt((float)(abs(a.x-b.x)*abs(a.x-b.x) + abs(a.y-b.y)*abs(a.y-b.y))); if(dist < 70) // DRAW mode { handPt.m_mode = CHandPoint::CIRCLE; handPt.m_nX = m_center.x, handPt.m_nY = m_center.y; } else { handPt.m_mode = CHandPoint::DRAW; findEndPoint(&handPt.m_nX, &handPt.m_nY); } } break; case 3: { CvPoint a = ptList[0], b = ptList[1], c = ptList[2]; dist = sqrt((float)(abs(a.x-b.x)*abs(a.x-b.x) + abs(a.y-b.y)*abs(a.y-b.y))); dist2 = sqrt((float)(abs(c.x-b.x)*abs(c.x-b.x) + abs(c.y-b.y)*abs(c.y-b.y))); if(abs(dist-dist2) < 10) { handPt.m_mode = CHandPoint::TRIANGE; handPt.m_nX = m_center.x, handPt.m_nY = m_center.y; } else { handPt.m_mode = CHandPoint::SETTING; } } break; case 4: handPt.m_mode = CHandPoint::RECT; handPt.m_nX = m_center.x, handPt.m_nY = m_center.y; break; case 5: handPt.m_mode = CHandPoint::STAR; handPt.m_nX = m_center.x, handPt.m_nY = m_center.y; break; default: handPt.m_mode = CHandPoint::NOTHING; break; } TCHAR buf[256] = {0,}; swprintf(buf, sizeof(buf), _T("%d\t%f\n"), fingerCnt, dist); ::OutputDebugString(buf); return handPt; }
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 }