亚洲mv大片欧洲mv大片入口,国产粉嫩无码一区二区三区,国内精品自产拍在线观看91,久久久亚洲欧洲日产国码二区,中文字幕人妻久久一区二区三区

常州機(jī)器視覺培訓(xùn)

常州上位機(jī)軟件開發(fā)

常州工業(yè)機(jī)器人編程設(shè)計(jì)培訓(xùn)

常州PLC培訓(xùn)

常州PLC

常州PLC編程培訓(xùn)

常州電工培訓(xùn)

常州和訊plc培訓(xùn)中心歡迎您!
當(dāng)前位置:網(wǎng)站首頁 > 新聞中心 新聞中心
使用Opencv多回形針角度-常州機(jī)器視覺培訓(xùn),常州上位機(jī)培訓(xùn)
日期:2024-5-11 14:17:06人氣:  標(biāo)簽:常州機(jī)器視覺培訓(xùn) 常州上位機(jī)培訓(xùn)

摘要

本篇來用OpenCV實(shí)現(xiàn)Halcon中一個(gè)計(jì)算回形針方向的實(shí)例clip.hdev,并構(gòu)建了計(jì)算角度函數(shù)和畫箭頭函數(shù),得到的角度與halcon例程相差無多。


 原圖如下:

image.png

 Halcon代碼比較簡單,這里也貼出來:


dev_update_window ('off')

read_image (Clip, 'clip')

get_image_size (Clip, Width, Height)

dev_close_window ()

dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowID)

dev_display (Clip)

set_display_font (WindowID, 14, 'mono', 'true', 'false')

disp_continue_message (WindowID, 'black', 'true')

stop ()

binary_threshold (Clip, Dark, 'max_separability', 'dark', UsedThreshold)

connection (Dark, Single)

select_shape (Single, Selected, 'area', 'and', 5000, 10000)

dev_set_draw ('fill')

dev_set_colored (12)

dev_display (Selected)

disp_continue_message (WindowID, 'black', 'true')

stop ()

dev_display (Clip)

dev_set_color ('green')

dev_display (Selected)

orientation_region (Selected, Phi)

area_center (Selected, Area, Row, Column)

dev_set_line_width (3)

dev_set_draw ('margin')

Length := 80

dev_set_color ('blue')

disp_arrow (WindowID, Row, Column, Row - Length * sin(Phi), Column + Length * cos(Phi), 4)

disp_message (WindowID, deg(Phi)$'3.1f' + ' deg', 'image', Row, Column - 100, 'black', 'false')

dev_update_window ('on')

image.png

  可以看到halcon的思路是:

    ① 讀取圖像 

    ② 二值化 

    ③ 根據(jù)面積剔除非回形針的region 

    ④ 計(jì)算每個(gè)region的方向和中心 

    ⑤ 畫箭頭,結(jié)果輸出 


但是opencv中沒有計(jì)算角度的函數(shù)和畫箭頭的函數(shù),因此需要我們自己定義。


opecv實(shí)現(xiàn):


 (一)構(gòu)建角度計(jì)算函數(shù)


double calLineAngle(Point&ptStrat, Point&ptEnd)

{

    const double PI = 3.1415926;

    double angle = 0;

    if (ptStrat.x==ptEnd.x)

    {

        angle = 90;

    }

    else if (ptStrat.y==ptEnd.y)

    {

        angle = 0;

    }

    else

    {

        angle = atan((double)(ptEnd.y - ptStrat.y) / (ptEnd.x - ptStrat.x))*(180 / PI);

        if (angle<0)

        {

            angle = abs(angle);

        }

        else if (angle>0)

        {

            angle = 180 - angle;

        }

        if (ptEnd.y-ptStrat.y>0&&ptEnd.x-ptStrat.x)

        {

            angle = angle - 180;

        }

        

    }

    return angle;

}

反正切函數(shù)atan與atan2的區(qū)別:


atan 和 atan2 都是求反正切函數(shù),如:有兩個(gè)點(diǎn) point(x1,y1), 和 point(x2,y2);那么這兩個(gè)點(diǎn)形成的斜率的角度計(jì)算方法分別是:


float angle = atan( (y2-y1)/(x2-x1) );


float angle = atan2( y2-y1, x2-x1 );


 atan 和 atan2 區(qū)別:


1:參數(shù)的填寫方式不同;


2:atan2 的優(yōu)點(diǎn)在于 如果 x2-x1等于0 依然可以計(jì)算,但是atan函數(shù)就會(huì)導(dǎo)致程序出錯(cuò);


 (二)構(gòu)建畫箭頭函數(shù)


void drawArrow(Mat&img, Point pStart, Point pEnd, int len, int alpha, Scalar color, int thickness, int lineType)

{

    const double PI = 3.1415926;

    Point arrow;

    //計(jì)算theat角

    double angel = atan2((double)(pStart.y - pEnd.y), (double)(pStart.x - pEnd.x));

    line(img, pStart, pEnd, color, thickness, lineType);

    //計(jì)算箭角邊的另一端的端點(diǎn)位置(上面的還是下面的要看箭頭的指向,即pStart和pEnd的位置)

    arrow.x = pEnd.x + len * cos(angel + PI * alpha / 180);

    arrow.y = pEnd.y + len * sin(angel + PI * alpha / 180);

    line(img, pEnd, arrow, color, thickness, lineType);

    arrow.x = pEnd.x + len * cos(angel - PI * alpha / 180);

    arrow.y = pEnd.y + len * sin(angel - PI * alpha / 180);

    line(img, pEnd, arrow, color, thickness, lineType);

}

 (三)主函數(shù)


int main(int argc, char** argv)

{

    double pointToLineDist(Point&pt, Point&lineStart, Point&lineEnd);

    double calLineAngle(Point&ptStrat, Point&ptEnd);

    void drawArrow(Mat&img, Point pStart, Point pEnd, int len, int alpha, Scalar color, int thickness, int lineType);



    Mat src = imread("D:/opencv練習(xí)圖片/回形針方向.png");

    imshow("輸入圖像", src);

    Mat gray, binary;

    cvtColor(src, gray, COLOR_BGR2GRAY);

    //閾值處理

    threshold(gray, binary, 150, 255, THRESH_BINARY_INV);

    imshow("二值化", binary);

    //尋找輪廓

    vector<vector<Point> > contours;

    findContours(binary, contours,  RETR_EXTERNAL, CHAIN_APPROX_NONE,Point());

    cout << contours.size() << endl;

    //輪廓分析,找到工件

    for (size_t i = 0; i < contours.size(); ++i)

    {

        //計(jì)算輪廓大小

        double area = contourArea(contours[i]);

        if (area < 12000)continue;

        double    max_dist = 0;

        Moments mm = moments(contours[i],false);

        Point ptCenter = Point(mm.m10 / mm.m00, mm.m01 / mm.m00);

        Point ptFarthest;

        for (int j = 0; j < contours[i].size(); j++)

        {

            double distance = sqrt(pow(contours[i][j].x - ptCenter.x, 2) + pow(contours[i][j].y - ptCenter.y, 2));

            if (distance>max_dist)

            {

                ptFarthest = Point(contours[i][j].x, contours[i][j].y);

                max_dist = distance;

            }

        }

        cout << max_dist << endl;

        drawContours(src, contours, i, Scalar(0, 0, 255), 5, 8);

        drawArrow(src, ptCenter, ptFarthest, 25, 30, Scalar(255,0,255), 3, 8);

        double angle = calLineAngle(ptCenter, ptFarthest);

        cout << angle << endl;

        char strAngle[20];

        sprintf_s(strAngle, "%0.1fdegree", angle);

        putText(src, strAngle, ptCenter, FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 255, 255), 2, 8);

    }

    imshow("結(jié)果", src);

    waitKey(0);

    return 0;

}

image.png

本文網(wǎng)址:
下一篇:沒有資料

相關(guān)信息:
版權(quán)所有 CopyRight 2006-2017 江蘇和訊自動(dòng)化設(shè)備有限公司 常州自動(dòng)化培訓(xùn)中心 電話:0519-85602926 地址:常州市新北區(qū)府琛商務(wù)廣場2號(hào)樓1409室
蘇ICP備14016686號(hào)-2 技術(shù)支持:常州山水網(wǎng)絡(luò)
本站關(guān)鍵詞:常州PLC培訓(xùn) 常州PLC編程培訓(xùn) 常州PLC編程 常州PLC培訓(xùn)班 網(wǎng)站地圖 網(wǎng)站標(biāo)簽
在線與我們?nèi)〉寐?lián)系
亚洲mv大片欧洲mv大片入口,国产粉嫩无码一区二区三区,国内精品自产拍在线观看91,久久久亚洲欧洲日产国码二区,中文字幕人妻久久一区二区三区