﻿{"id":995,"date":"2012-11-06T13:54:23","date_gmt":"2012-11-06T05:54:23","guid":{"rendered":"http:\/\/nick.workao.org\/?p=995"},"modified":"2021-11-17T11:33:14","modified_gmt":"2021-11-17T03:33:14","slug":"%e5%a6%82%e4%bd%95%e7%94%a8%e6%91%84%e5%83%8f%e5%a4%b4%e6%9d%a5%e6%b5%8b%e8%b7%9d%ef%bc%88opencv%ef%bc%89","status":"publish","type":"post","link":"http:\/\/nick.txtcc.com\/index.php\/linux\/995","title":{"rendered":"\u3010\u8f6c\u3011\u5982\u4f55\u7528\u6444\u50cf\u5934\u6765\u6d4b\u8ddd\uff08opencv\uff09"},"content":{"rendered":"<p align=\"center\">\u00a0 \u00a0 \u00a0 \u00a0\u6700\u8fd1\u4e00\u76f4\u5fd9\u7740\u627e\u5de5\u4f5c\uff0cblog\u90fd\u957f\u8349\u4e86\uff0c\u4eca\u5929\u628a\u4ee5\u524d\u4f5c\u7684\u4e00\u4e2a\u4e1c\u897f\u653e\u4e0a\u6765\u5145\u5145\u95e8\u9762\u5427\u3002\u8bb0\u5f97\u5728\u54ea\u770b\u5230\u8fc7\u8001\u5916\u505a\u7684\u8fd9\u4e2a\u4e1c\u897f\uff0c\u89c9\u5f97\u5f88\u597d\u73a9\uff0c\u5c31\u81ea\u5df1\u4e5f\u505a\u4e86\u4e00\u4e2a\u3002\u5728\u6444\u50cf\u5934\u4e0b\u9762\u56fa\u5b9a\u4e00\u4e2a\u6fc0\u5149\u7b14\uff0c\u5c31\u6784\u6210\u4e86\u8fd9\u4e2a\u7b80\u6613\u7684\u6d4b\u8ddd\u88c5\u7f6e\u3002\u770b\u4e00\u4e0b\u56fe\u5427\u3002<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055425hPP.jpg\" alt=\"\"><\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055426MaB.jpg\" alt=\"\"><\/p>\n<p align=\"left\">\u00a0\u00a0<strong>\u539f \u7406<\/strong><\/p>\n<p align=\"left\">\u00a0 \u5047\u8bbe\u6fc0\u5149\u675f\u662f\u4e0e\u6444\u50cf\u5934\u7684\u5149\u8f74\u5b8c\u5168\u5e73\u884c\uff0c\u6fc0\u5149\u675f\u7684\u4e2d\u5fc3\u843d\u70b9\u5728\u5728\u6444\u50cf\u5934\u7684\u89c6\u57df\u4e2d\u662f\u6700\u4eae\u7684\u70b9\u3002\u6fc0\u5149\u675f\u7167\u5c04\u5230\u6444\u50cf\u5934\u89c6\u57df\u4e2d\u7684\u8ddf\u8e2a\u76ee\u6807\u4e0a\uff0c\u90a3\u4e48\u6444\u50cf\u5934\u53ef\u4ee5\u6355\u6349\u5230\u8fd9\u4e2a\u70b9\uff0c\u901a\u8fc7\u7b80\u5355\u7684\u56fe\u50cf\u5904\u7406\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5728\u8fd9\u4fa6\u56fe\u50cf\u4e2d\u627e\u5230\u6fc0\u5149\u675f\u7167\u5c04\u5f62\u6210\u7684\u6700\u4eae\u70b9\uff0c\u540c\u65f6\u53ef\u4ee5\u8ba1\u7b97\u51faY\u8f74\u4e0a\u65b9\u5411\u4e0a\u4ece\u843d\u70b9\u5230\u56fe\u50cf\u4e2d\u5fc3\u7684\u8c61\u7d20\u7684\u4e2a\u6570\u3002\u8fd9\u4e2a\u843d\u70b9\u8d8a\u63a5\u8fd1\u56fe\u50cf\u7684\u4e2d\u5fc3\uff0c\u88ab\u6d4b\u7269\u4f53\u8ddd\u79bb\u673a\u5668\u4eba\u5c31\u8d8a\u8fdc\u3002\u7531\u4e0b\u56fe\u56fe\u53ef\u4ee5\u8ba1\u7b97\u8ddd\u79bbD\uff1a<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055428rbP.jpg\" alt=\"\"><\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055429wAB.jpg\" alt=\"\">\uff081\uff09<\/p>\n<p align=\"left\">\u00a0 \u7b49\u5f0f\u4e2dh\u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u662f\u6444\u50cf\u5934\u4e0e\u6fc0\u5149\u53d1\u5c04\u5668\u4e4b\u95f4\u7684\u5782\u76f4\u8ddd\u79bb\uff0c\u53ef\u4ee5\u76f4\u63a5\u6d4b\u91cf\u83b7\u5f97\u3002<\/p>\n<div>\u03b8\u53ef\u901a\u8fc7\u4e0b\u5f0f\u8ba1\u7b97\uff1a<\/div>\n<div>\u03b8=Num*Rop+Offset\u00a0\u00a0\u00a0\u00a0\u00a0 \uff082\uff09<\/div>\n<div>\u5176\u4e2d\uff1aNum\u662f\u4ece\u56fe\u50cf\u4e2d\u5fc3\u5230\u843d\u70b9\u7684\u50cf\u7d20\u4e2a\u6570<\/div>\n<div>Rop\u662f\u6bcf\u4e2a\u50cf\u7d20\u7684\u5f27\u5ea6\u503c<\/div>\n<div>Offset\u662f\u5f27\u5ea6\u8bef\u5dee<\/div>\n<div>\u5408\u5e76\u4ee5\u4e0a\u7b49\u5f0f\u53ef\u4ee5\u5f97\u5230\uff1a<\/div>\n<div><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055433rCr.jpg\" alt=\"\">\uff083\uff09<\/div>\n<div><\/div>\n<div>Num\u53ef\u4ee5\u4ece\u56fe\u50cf\u4e0a\u8ba1\u7b97\u5f97\u5230\u3002Rop\u548cOffset\u9700\u8981\u901a\u8fc7\u5b9e\u9a8c\u8ba1\u7b97\u83b7\u5f97\u3002\u9996\u5148\u6d4b\u91cf\u51faD\u7684\u51c6\u786e\u503c\uff0c\u7136\u540e\u6839\u636e\u7b49\u5f0f\uff081\uff09\u53ef\u4ee5\u8ba1\u7b97\u51fa\u51c6\u786e\u7684\u03b8\uff0c\u6839\u636e\u7b49\u5f0f\uff082\uff09\u53ef\u5230\u53ea\u542b\u6709\u53c2\u6570Rop\u548cOffset\u7684\u65b9\u7a0b\u3002\u5728\u4e0d\u540c\u7684\u8ddd\u79bb\u591a\u6b21\u6d4b\u91cfD\u7684\u51c6\u786e\u503c\u8ba1\u7b97\u03b8\uff0c\u6c42\u89e3\u65b9\u7a0b\u7ec4\u53ef\u4ee5\u6c42\u51faRop\u548cOffset\u3002\u8fd9\u91ccRop\uff1d0.0030354\uff0cOffset\uff1d0.056514344\u3002<\/div>\n<div><img decoding=\"async\" src=\"http:\/\/nick.txtcc.com\/wp-content\/uploads\/remote_image\/2012\/11\/055438oGO.jpg\" alt=\"\"><\/div>\n<div><\/div>\n<div><strong>\u7a0b \u5e8f<\/strong><\/div>\n<div>\u5934\u6587\u4ef6\uff1a<\/div>\n<div><span style=\"color: #333399;\">class LaserRange\n{\npublic:\nstruct RangeResult * GetRange(IplImage * imgRange,IplImage * imgDst);\nLaserRange();\nvirtual ~LaserRange();\n<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">private:\nunsigned\u00a0\u00a0 int maxW;\nunsigned\u00a0\u00a0 int maxH;\nunsigned\u00a0\u00a0 int MaxPixel;\nRangeResult * strctResult;<\/span><\/span>\n<span style=\"color: #339966;\">\/\/ Values used for calculating range from captured image data<\/span>\nconst double\u00a0gain;\u00a0<span style=\"color: #339966;\"><span style=\"color: #339966;\">\/\/ Gain Constant used for converting pixel offset to angle in radians<\/span>\n<\/span>\u00a0const double\u00a0offset;<span style=\"color: #99cc00;\"><span style=\"color: #000000;\">\u00a0<\/span>\n<span style=\"color: #339966;\">\/\/ Offset Constant<\/span>\n<\/span>\u00a0const double\u00a0h_cm;\u00a0\u00a0<span style=\"color: #339966;\">\/\/ Distance between center of camera and laser<\/span>\nunsigned int\u00a0pixels_from_center;\u00a0<span style=\"color: #339966;\">\/\/ Brightest pixel location from center\n<\/span>\n\n<\/div>\n<div><span style=\"color: #333399;\">\u00a0void Preprocess(void * img,IplImage * imgTemp);\n};<\/span><\/div>\n<div><\/div>\n<div><span style=\"color: #000000;\">cpp\u6587\u4ef6\uff1a<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">LaserRange::LaserRange():gain(0.0030354),offset(0),h_cm(4.542)\n{\nmaxW=0;\nmaxH=0;\nMaxPixel=0;<\/span><\/span>pixels_from_center=0;\n\n<span style=\"color: #339966;\">\/\/ Brightest pixel location from center<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0 strctResult=new RangeResult;<\/span><\/span>strctResult->maxCol=0;\nstrctResult->maxRow=0;\nstrctResult->maxPixel=0;\nstrctResult->Range=0.0;\n}\n\n<\/div>\n<div><span style=\"color: #333399;\">LaserRange::~LaserRange()\n{\nif(NULL!=strctResult) delete strctResult;\n}<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">struct RangeResult * LaserRange::GetRange(IplImage * imgRange,IplImage * imgDst)\n{\nif(NULL==imgRange) return\u00a0\u00a0 strctResult;\nPreprocess(imgRange,imgDst);<\/span><\/span>pixels_from_center = abs(120-maxH);\n\n<\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0\/\/ Calculate range in cm based on bright pixel location, and setup specific constants\nstrctResult->Range= h_cm\/tan(pixels_from_center * gain + offset);<\/span><\/span>strctResult->PixfromCent=pixels_from_center;\nstrctResult->maxCol=maxW;\nstrctResult->maxRow=maxH;\nstrctResult->maxPixel=MaxPixel;\n\/\/strctResult->Range=0.0;\nreturn\u00a0 strctResult;\n}\n\n<\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">void LaserRange::Preprocess(void *img, IplImage * imgTemp)\n{\nMaxPixel=0;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #339966;\">\u00a0 \/\/\u5904\u7406\u4e0b\u4e00\u5e27\u524d \u6700\u5927\u50cf\u7d20\u503c\u6e05\u96f6\uff1b\n<\/span>\u00a0\u00a0 IplImage* image = reinterpret_cast<IplImage*>(img);<\/span><\/span>cvCvtPixToPlane( image,0 ,0 ,imgTemp , 0);\n\nfor( int j=((imgTemp->width-60)\/2-1); j<(imgTemp->width-40)\/2+59; j++)\n{\nfor(int i=5; i<imgTemp->height-5; i++)\n{\n\nif((imgTemp->imageData[i*imgTemp->widthStep+j])>MaxPixel)\n{\nif( ((imgTemp->imageData[(i-1)*imgTemp->widthStep+j])>MaxPixel) &#038;&#038; ((imgTemp->imageData[(i-1)*imgTemp->widthStep+j+1])>MaxPixel) &#038;&#038;((imgTemp->imageData[(i-1)*imgTemp->widthStep+j-1])>MaxPixel)\u00a0\u00a0 )\n{\nif( ((imgTemp->imageData[(i+1)*imgTemp->widthStep+j])>MaxPixel) &#038;&#038; ((imgTemp->imageData[(i+1)*imgTemp->widthStep+j+1])>MaxPixel) &#038;&#038;((imgTemp->imageData[(i+1)*imgTemp->widthStep+j-1])>MaxPixel)\u00a0\u00a0 )\n{\nif((imgTemp->imageData[i*(imgTemp->widthStep)+j+1])>MaxPixel)\n{\nif((imgTemp->imageData[i*(imgTemp->widthStep)+j-1])>MaxPixel)\n{\nMaxPixel=imgTemp->imageData[i*imgTemp->widthStep+j] ;\nmaxW=j;\nmaxH=i;\n}\n}\n}\n}\n}\n}\n\n}\n\n<\/div>\n<div><\/div>\n<div><span style=\"color: #000000;\">\u8c03\u7528\u51fd\u6570\uff1a<\/span><\/div>\n<div><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">int CLaserVisionDlg::CaptureImage()\n{\n<span style=\"color: #339966;\">\/\/ CvCapture* capture = 0;<\/span><\/span><\/span>\/\/ capture = cvCaptureFromCAM(0);\u00a0 \/\/0\u8868\u793a\u8bbe\u5907\u53f7\n\n<span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0\u00a0\u00a0 if( !capture )\n{\nfprintf(stderr,&#8221;Could not initialize capturing&#8230;\/n&#8221;);\nreturn -1;\n}<\/span><\/span>\n<span style=\"color: #339966;\">\u00a0\/\/ cvNamedWindow( &#8220;LaserRangeImage&#8221;, 1 );\n\/\/ cvvNamedWindow( &#8220;image&#8221;, 1);\n<\/span>\u00a0\u00a0 cvvNamedWindow( &#8220;Dimage&#8221;, 1);\n\nfor(;;)\n{\nIplImage* frame = 0;\n\nif(isStop) break;\n\n<\/div>\n<div><span style=\"color: #333399;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 frame = cvQueryFrame( capture );\u00a0<span style=\"color: #339966;\">\/\/\u4ece\u6444\u50cf\u5934\u6293\u53d6\u4e00\u526f\u56fe\u50cf\u6846\u67b6\n<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if( !frame )\nbreak;<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if( !imgOrign )\n{\n<span style=\"color: #339966;\">\u00a0\/\/allocate all the buffers\n<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 imgOrign = cvCreateImage( cvGetSize(frame), 8, 3 );\u00a0\u00a0<span style=\"color: #339966;\">\u00a0 \/\/\u521b\u5efa\u4e00\u526f\u56fe\u50cf\n<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 imgOrign->origin = frame->origin;<\/span><\/span>}\n\n<\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cvCopy( frame, imgOrign, 0 );\u00a0\u00a0<span style=\"color: #339966;\">\/\/\u5c06\u56feframe\u590d\u5236\u5230image\n<\/span>\u00a0\u00a0\/\/cvShowImage(&#8220;LaserRangeImage&#8221;,imgOrign);<\/span><\/span>if(!imgDest)\n{\nimgDest=cvCreateImage( cvSize( imgOrign->width,imgOrign->height),8,1);\ncvZero( imgDest );\n}\nstruct RangeResult * temp= laservsion.GetRange(imgOrign,imgDest);\n\n<\/div>\n<div><span style=\"color: #333399;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cvLine( imgOrign,cvPoint(temp->maxCol,0), cvPoint(temp->maxCol,imgOrign->height),cvScalar(100,100,255,0),1,8,0);\ncvLine( imgOrign,cvPoint(0,temp->maxRow), cvPoint(imgOrign->width,temp->maxRow),cvScalar(100,100,255,0),1,8,0);<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\n<span style=\"color: #339966;\">\u00a0 \/\/ cvvShowImage( &#8220;image&#8221;, imgOrign);\n<\/span>\u00a0\u00a0cvSaveImage(&#8220;image.bmp&#8221;, imgOrign);<\/span><\/span>cvvShowImage( &#8220;Dimage&#8221;, imgDest);\n\n<span style=\"color: #339966;\">\u00a0\/\/\u5728PictureBox\u4e0a\u663e\u793a\u56fe\u7247\n<\/span>\u00a0\u00a0CDC* pDC = GetDlgItem(IDC_Picture)->GetDC();\nCDC dcmemory;\nBITMAP bm;\ndcmemory.CreateCompatibleDC(pDC);\nCBitmap* pBmp;\nCString szFileName = &#8220;image.bmp&#8221;;\nHBITMAP hBk = (HBITMAP)::LoadImage(NULL,szFileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);\nif(NULL!=hBk)\n{\npBmp=CBitmap::FromHandle(hBk);\npBmp->GetObject(sizeof(BITMAP), &#038;bm);\ndcmemory.SelectObject(pBmp);\npDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &#038;dcmemory, 0, 0, SRCCOPY);\n\n<\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #333399;\">\u00a0\u00a0\u00a0 }<\/span><\/span>char str[80];\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #339966;\">\u00a0\/\/ To print message\n<\/span>\u00a0\u00a0\u00a0 CDC *pDCp= GetDC();\nchar str2[80];\n\n<span style=\"color: #339966;\">\u00a0\/\/ Display frame coordinates as well as calculated range\n<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sprintf(str, &#8220;Pix Max Value=%d\u00a0 At x= %u, y= %u, PixfromCent= %d&#8221;,temp->maxPixel,temp->maxCol, temp->maxRow, temp->PixfromCent);\nsprintf(str2, &#8220;Range= %f cm &#8220;,temp->Range);\npDCp->TextOut(30, 33, str);\npDCp->TextOut(50, 50, str2);\nReleaseDC(pDCp);\n\nint\u00a0 c = cvWaitKey(10);\n<span style=\"color: #339966;\">\/\/\u00a0 if( c == &#8216;q&#8217; )\n\/\/\u00a0\u00a0\u00a0\u00a0 break;\n<\/span>\n\n<\/div>\n<div><span style=\"color: #333399;\">\u00a0}<\/span><\/div>\n<div><span style=\"color: #333399;\"><span style=\"color: #339966;\">\/\/cvReleaseCapture( &#038;capture );\n\/\/cvDestroyWindow(&#8220;LaserRangeImage&#8221;);\n\/\/ cvDestroyWindow( &#8220;image&#8221;);\n<\/span>\u00a0cvDestroyWindow( &#8220;Dimage&#8221;);\nreturn 0;\n}<\/span><\/div>\n<div><\/div>\n<div>\u539f\u6587\uff1ahttp:\/\/blog.csdn.net\/xylary\/article\/details\/1843809<\/div>","protected":false},"excerpt":{"rendered":"<p>\u00a0 \u00a0 \u00a0 \u00a0\u6700\u8fd1\u4e00\u76f4\u5fd9\u7740\u627e\u5de5\u4f5c\uff0cblog\u90fd\u957f\u8349\u4e86\uff0c\u4eca\u5929\u628a\u4ee5\u524d\u4f5c\u7684\u4e00\u4e2a\u4e1c\u897f\u653e\u4e0a\u6765\u5145\u5145\u95e8\u9762\u5427\u3002\u8bb0\u5f97\u5728\u54ea\u770b\u5230\u8fc7\u8001\u5916\u505a\u7684\u8fd9\u4e2a\u4e1c\u897f\uff0c\u89c9\u5f97\u5f88\u597d\u73a9\uff0c\u5c31\u81ea\u5df1\u4e5f\u505a\u4e86\u4e00\u4e2a\u3002\u5728\u6444\u50cf\u5934\u4e0b\u9762\u56fa\u5b9a\u4e00\u4e2a\u6fc0\u5149\u7b14\uff0c\u5c31\u6784\u6210\u4e86\u8fd9\u4e2a\u7b80\u6613\u7684&#46;&#46;&#46;<\/p>","protected":false},"author":1,"featured_media":996,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-995","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux"],"_links":{"self":[{"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/posts\/995","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/comments?post=995"}],"version-history":[{"count":4,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/posts\/995\/revisions"}],"predecessor-version":[{"id":2233,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/posts\/995\/revisions\/2233"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/media\/996"}],"wp:attachment":[{"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/media?parent=995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/categories?post=995"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nick.txtcc.com\/index.php\/wp-json\/wp\/v2\/tags?post=995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}