Ren Jie Lee 2019-06-10 13:28 采纳率: 0%
浏览 339

OpenCV中對vector<Mat>添加return返還

如題,小弟最近在做有關opencv的程式,是關於找出鏡頭畫面之藍色區域並且計算邊長與旋轉角度,由於有時跳出 vector subscript out of range 這段程式碼,後來發現是因為如果攝像機沒有出現目標設定之藍色區域,此時vector會超出他的範圍,如果我想添加一段判斷式在vector channels; 這邊,判斷當vector範圍超出時返還,則該判別式
該如何寫? 小弟試過幾次結果並不成功,還請各位前輩指教一下,以下放是片段程式碼

int main()
{
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << " Camera Has Been Opened !" << endl;
return -1;
}

Mat frame;
while (1)   //儲存WebCam上面之畫面
{
    cap >> frame;
    imwrite("C:/Navigation/WebCam_Image.jpg", frame);

    if (frame.empty())
    {
        cout << " Error Writing the Image !" << endl;
        return -4;
    }

    line(frame, Point(0, 240), Point(640, 240), Scalar(0, 255, 0), 1, CV_AA);
    line(frame, Point(320, 0), Point(320, 480), Scalar(0, 255, 0), 1, CV_AA);

    imshow("WebCam", frame);
    if (waitKey(1) == 27)
    {
        break;
    }
}

//Blue //留住
Mat srcImg, midImg, dstImg;
srcImg = imread("C:/Navigation/WebCam_Image.jpg"); //C:/Lock Mouse/WebCam_Image.jpg  //C:/Navigation/5.png
Mat xianshi = srcImg.clone();
Mat redChannel, greenChannel, blueChannel;
//namedWindow("【Original】", WINDOW_AUTOSIZE);
//imshow("【Original】", srcImg);

//0.灰階
Mat grayImg;
vector<Mat> channels;
split(srcImg, channels);
//cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);

grayImg = channels.at(0);  //對藍色區域取灰階圖

redChannel = channels.at(2);
greenChannel = channels.at(1);
blueChannel = channels.at(0);
//namedWindow("【Blue 灰度圖】", WINDOW_AUTOSIZE);
//imshow("【Blue 灰度圖】", grayImg);

//1.均值濾波
blur(grayImg, grayImg, Size(20, 20), Point(-1, -1));
//namedWindow("【均值濾波後】", WINDOW_NORMAL);
//imshow("【均值濾波後】", grayImg);

//2.轉化為二值圖
Mat midImg1 = grayImg.clone();
int rowNumber = midImg1.rows;
int colNumber = midImg1.cols;

for (int i = 0; i < rowNumber; i++)   //僅限定天藍色區域
{
    uchar* data = midImg1.ptr<uchar>(i); //取第i行的首地址
    uchar* redData = redChannel.ptr<uchar>(i);
    for (int j = 0; j < colNumber; j++)
    {
        if (data[j] > BIN_DIV&&redData[j] < BIN_DIV * 2 / 3)
            data[j] = 255;
        else
            data[j] = 0;
    }
}

namedWindow("【Blue 二值圖】", WINDOW_AUTOSIZE);
imshow("【Blue 二值圖】", midImg1);
Mat midImg2 = midImg1.clone();
Mat element = getStructuringElement(MORPH_RECT, Size(50, 50));
morphologyEx(midImg1, midImg2, MORPH_CLOSE, element);
namedWindow("【Blue 開運算後】", WINDOW_AUTOSIZE);
imshow("【Blue 開運算後】", midImg2);
//cout << "midImg1.channel=" << midImg1.channels() << endl;
//cout << "mdiImg1.depth" << midImg1.depth() << endl;

//3.查找圖像輪廓
Mat midImg3 = Mat::zeros(midImg2.rows, midImg2.cols, CV_8UC3);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(midImg2, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);

for (int index = 0; index >= 0; index = hierarchy[index][0])
{
    Scalar color(255, 255, 255);
    drawContours(midImg3, contours, index, color, NULL, 8, hierarchy);
}
//namedWindow("【輪廓圖】", WINDOW_NORMAL);
//imshow("【輪廓圖】", midImg3);
Mat midImg4 = midImg3.clone();

//4.創建包圍輪廓的矩形邊界
int cnt = 0;
for (int i = 0; i < contours.size(); i++)
{
    //float length, length2, midx, midy, midx2, midy2;
    static int length, length2, midx, midy, midx2, midy2;
    float ang, m, pixel_area, pixel_length, pixel_length2, dis;

    //每個輪廓
    vector<Point> points = contours[i];

    //對給定的2D點集,尋找最小面積的包圍矩形
    RotatedRect box = minAreaRect(Mat(points));
    Point2f vertex[4];
    box.points(vertex);

    //繪製出最小面積的包圍矩形
    line(xianshi, vertex[0], vertex[1], Scalar(100, 200, 211), 2, CV_AA);
    line(xianshi, vertex[1], vertex[2], Scalar(100, 200, 211), 2, CV_AA);
    line(xianshi, vertex[2], vertex[3], Scalar(100, 200, 211), 2, CV_AA);
    line(xianshi, vertex[3], vertex[0], Scalar(100, 200, 211), 2, CV_AA);
    //cout << " [" << i << "]  (" << vertex[i].x << "," << vertex[i].y << ")" << endl;  //印出座標

    //總共 i 個圖形,共 4 * i 個交點
    if (i == 0)
    {
        for (int i = 0; i < 4; i++)
        {
            circle(xianshi, Point(vertex[i].x, vertex[i].y), 8, Scalar(0, 255, 0), 1);  //綠色實心角點 **
            //將 4 * i 個交點儲存
            vertexx[i] = vertex[i].x;
            vertexy[i] = vertex[i].y;
        }
    }
    else
    {
        for (int j = 0; j < 4; j++)
        {
            circle(xianshi, Point(vertex[j].x, vertex[j].y), 8, Scalar(0, 255, 0), 1);  //綠色實心角點 **
            //將 4*i 個交點儲存
            vertexx[j + (i * 4)] = vertex[j].x;
            vertexy[j + (i * 4)] = vertex[j].y;
        }
    }

    //計算長度
    pixel_length = sqrt((vertex[0].x - vertex[1].x)*(vertex[0].x - vertex[1].x) + (vertex[0].y - vertex[1].y)*(vertex[0].y - vertex[1].y));
    midx = abs((vertex[0].x - vertex[1].x) / 2) + vertex[1].x;
    midy = abs((vertex[0].y - vertex[1].y) / 2) + vertex[1].y;

    pixel_length2 = sqrt((vertex[1].x - vertex[2].x)*(vertex[1].x - vertex[2].x) + (vertex[1].y - vertex[2].y)*(vertex[1].y - vertex[2].y));  //3.625
    midx2 = abs((vertex[1].x - vertex[2].x) / 2) + vertex[1].x;
    midy2 = abs((vertex[1].y - vertex[2].y) / 2) + vertex[2].y;

    //Area
    pixel_area = pixel_length * pixel_length2;
    //cout << " Pixel_Length = " << pixel_length << " , Pixel_Length2 = " << pixel_length2 << endl;
    //cout << (" Pixel_Area ") << i << (" = ") << pixel_area << endl;
    mag = (pixel_length + pixel_length2) / (2 * 31);

    length = pixel_length / mag;
    length2 = pixel_length2 / mag;

    sprintf_s(text, "%dmm", length);
    putText(xianshi, text, Point(midx, midy), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**
    circle(xianshi, Point(midx, midy), 4, Scalar(0, 255, 0), 1);  //綠色實心角點 **
    sprintf_s(text, "%dmm", length2);
    putText(xianshi, text, Point(midx2, midy2), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**
    circle(xianshi, Point(midx2, midy2), 4, Scalar(0, 255, 0), 1);  //綠色實心角點 **

    //Angle
    m = (vertex[0].y - vertex[1].y) / (vertex[0].x - vertex[1].x);
    ang = atan(m)*(180 / pi);
    //cout << ("m = ") << m << endl;
    cout << (" Angle ") << i << (" = ") << 90 - ang << endl;

    //Distance
    dis = (6.15 * 110) / mag;
    cout << " Distance = " << dis << " mm" << endl;

    //mark
    sprintf_s(text, "%d", i);
    putText(xianshi, text, Point(midx + 50, midy + 50), fontFace, fontScale, Scalar(255, 255, 255), thickness, 1); //**

    //繪製中心的光標
    Point s1, l, r, u, d;
    s1.x = (vertex[0].x + vertex[2].x) / 2.0;
    s1.y = (vertex[0].y + vertex[2].y) / 2.0;
    l.x = s1.x - 10;
    l.y = s1.y;

    r.x = s1.x + 10;
    r.y = s1.y;

    u.x = s1.x;
    u.y = s1.y - 10;

    d.x = s1.x;
    d.y = s1.y + 10;
    line(xianshi, l, r, Scalar(255, 255, 255), 1, CV_AA);  //水平
    capx = r.x - 10;
    navx[i] = capx;
    line(xianshi, u, d, Scalar(255, 255, 255), 1, CV_AA);  //垂直
    capy = d.y - 10;
    navy[i] = capy;
    cout << (" Object Number = ") << i << (", Mid x = ") << capx << (", Mid y = ") << capy << endl;
    cout << endl;
}
for (int i = 0; i < contours.size(); i++)
{
    navx[25];
    navy[25];
    //cout << ("i = ") << i << (", navx = ") << navx[i] << (", navy = ") << navy[i] << endl;
}
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-20 17:55
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程