数字近景工业摄影测量中Schneider编码标志的自动生成程序

本文介绍了一种用于数字近景工业摄影测量的Schneider编码标志自动生成程序。该程序能够根据Schneider编码方案,利用OpenCV绘制不同位数的编码标志,并通过循环移位操作确定最终编码值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数字近景工业摄影测量中Schneider编码标志的自动生成程序

前言

在数字近景摄影测量中,最关键的图像间的匹配。但是由于工业测量现场复杂的背景和被测物体表面没有足够的特征,应用在双目视觉中基于关键点匹配的算法在效率、精度、准确率等方面,大多不能满足需求。于是在工业数字近景测量中需要人工设置的靶标点作为关键点进行匹配。
人工设置的靶标有很多种,目前最主要的点分布型,同心圆环型,非几何特征型。本文利用程序实现了同心圆环型中Schneider C .T设计的靶标的自动生成。

Schneider 编码方案介绍

它由中心圆和同心编码环带组成,编码环带按照角度均分为10份,每份36°,每一份可以称为亮环带或者暗环带,相应的二进制码为1或者0,“1”表示该位上有编码点,“0”表示该位上没有编码点,由于编码环带并没有规定起始点,以任意一个编码点为起始位置,按顺时针方向读取编码环带的码值, 可以组成长度为 10的二进制序列,对这个二进制序列进行循环移位,选取其中数值最小的二进制序列作为该靶标的码值。

自动生成编码代码

该方法采用opencv实现画圆和部分圆环。

主函数

int main()
{
    //8位的二进制数循环移位
    vector<int> queue;
    uint16_t isexist[40000] = { 0 };
    vector<int> result;
    int piccount = 0;
    for (uint16_t i = 1; i < pow(2,BIT); i++)
    {
        //判断该数是否在队列
        if(isexist[i] == 1)
            continue;

        //把该数对应的8个移位数据放入队列
        for (int j = 0; j < BIT; j++)
            isexist[move(i, j, BIT)] = 1;

        //用该数生成一个图片
        int picsize = 1000;
        int radius1 = 150;
        int radius2 = 300;
        int radius3 = 400;
        Mat temp = Mat::zeros(Size(picsize, picsize), CV_8UC1);
        if(INVERT)
            bitwise_not(temp, temp);

        //先画一个圆
        if (INVERT)
            circle(temp, Point(picsize / 2, picsize / 2), radius1, CV_RGB(0, 0, 0), -1);
        else
            circle(temp, Point(picsize / 2, picsize / 2), radius1, CV_RGB(0, 0, 255), -1);

        //画BIT个扇形
        for (int k = 0; k < BIT; k++)
        {
            if (i & (unsigned int)(pow(2, k)))
            {
                vector<vector<Point>> contours;
                vector<Point> contour;
                Point p0;

                float range = 360.0 / BIT;
                for (int angle = range * k; angle <= range*(k + 1); angle = angle + 1)
                {
                    p0 = Point(picsize / 2 + radius2 * cos(angle / 180.0*3.1416),
                        picsize / 2 + radius2 * sin(angle / 180.0*3.1416));
                    contour.push_back(p0);
                }
                for (int angle = range * (k + 1); angle >= range*k; angle = angle - 1)
                {
                    p0 = Point(picsize / 2 + radius3 * cos(angle / 180.0*3.1416),
                        picsize / 2 + radius3 * sin(angle / 180.0*3.1416));
                    contour.push_back(p0);
                }
                contours.push_back(contour);
                if(INVERT)
                    drawContours(temp, contours, -1, CV_RGB(0, 0, 0), -1);
                else
                    drawContours(temp, contours, -1, CV_RGB(0, 0, 255), -1);
            }
        }

        //保存图片
        string filename;
        if (INVERT) 
        {
            createDirectory(to_string(BIT) + "反/");
            filename = to_string(BIT) + "反/" + to_string(i) + ".bmp";
        }
        else
        {
            createDirectory(to_string(BIT) + "/");
            filename = to_string(BIT) + "/" + to_string(i) + ".bmp";
        }

        //保存图片
        imwrite(filename, temp);
        piccount++;
        result.push_back(i);
    }

    cout << piccount << endl;
    for (int i = 0; i < result.size(); i++)
        cout << result[i] << "\t";
    cout << endl;

    while(1);
    return 0;
}

调用的函数1:循环移位操作

/*
参数说明:
number:要移位的数
c:要移的位数
bit:总共有几位,默认为8
*/
uint16_t move(uint16_t number, uint8_t c, uint8_t bit = 8)
{
    //首先判读输入的是否合理
    if (number < 0 && number >= pow(2, bit))
        cout << "输入的参数1:" << number << "不合理!" << endl;

    if (c >= bit)
        cout << "输入的参数2" << c << "不合理!" << endl;

    uint16_t a = number;

    uint16_t left = 0;//存储左移之后的结果
    uint16_t right = 0;//存储右移之后的结果
    uint16_t mask = pow(2, bit) - 1;

    right = ((a & mask) >> c) & mask;
    left = ((a & mask) << (bit - c)) & mask;

    uint16_t result;
    result = left | right;

    return result;
}

调用的函数2:创建目录函数

bool createDirectory(const std::string folder) 
{
    std::string folder_builder;
    std::string sub;
    sub.reserve(folder.size());
    for (auto it = folder.begin(); it != folder.end(); ++it)
    {
        //cout << *(folder.end()-1) << endl;
        const char c = *it;
        sub.push_back(c);
        if (c == '\\' || it == folder.end() - 1)
        {
            folder_builder.append(sub);
            if (0 != ::_access(folder_builder.c_str(), 0))
            {
                // this folder not exist
                if (0 != ::_mkdir(folder_builder.c_str()))
                {
                    // create failed
                    return false;
                }
            }
            sub.clear();
        }
    }
    return true;
}

生成图片展示

4位编码

这里写图片描述

这里写图片描述

8位编码

这里写图片描述
这里写图片描述

12位编码(不是全部)

这里写图片描述
这里写图片描述

程序下载

程序工程目录截图

这里写图片描述

下载地址:

https://download.youkuaiyun.com/download/iamqianrenzhan/10562068

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元点机智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值