小编Tim*_*imo的帖子

为什么std :: any_cast不支持隐式转换?

当从实际存储类型到请求类型的隐式转换可能时,为什么std::any_cast抛出std::bad_any_cast异常?

例如:

std::any a = 10;  // holds an int now
auto b = std::any_cast<long>(a);   // throws bad_any_cast exception
Run Code Online (Sandbox Code Playgroud)

为什么这是不允许的,是否有允许隐式转换的解决方法(如果std::any保存的确切类型未知)?

c++ c++17

33
推荐指数
3
解决办法
3472
查看次数

C++ 17 - 嵌套结构化绑定可能吗?

假设我有一个类型的对象

std::map<std::string, std::tuple<int, float>> data;
Run Code Online (Sandbox Code Playgroud)

是否可以以嵌套的方式访问元素类型(例如,当在ranged for循环中使用时)

for (auto [str, [my_int, my_float]] : data) /* do something */
Run Code Online (Sandbox Code Playgroud)

c++ c++17 structured-bindings

27
推荐指数
2
解决办法
1645
查看次数

使用OpenCV进行矩形检测/跟踪

我需要的

我目前正致力于增强现实游戏.游戏使用的控制器(我在这里谈论的是物理输入设备)是单色的,长方形的纸片.我必须在摄像机的捕获流中检测该矩形的位置,旋转和大小.检测应在尺度上不变,并且在沿X和Y轴旋转时不变.

在用户将纸张移开或朝向相机移动的情况下,需要比例不变性.我不需要知道矩形的距离,因此尺度不变性转换为尺寸不变性.

如果用户沿其局部X和/或Y轴倾斜矩形,则需要旋转不变性.这种旋转将纸张的形状从矩形变为梯形.在这种情况下,面向对象的边界框可用于测量纸张的尺寸.

我做了什么

开始时有一个校准步骤.窗口显示摄像机源,用户必须单击矩形.单击时,鼠标指向的像素颜色将作为参考颜色.帧被转换为HSV颜色空间以改善颜色区分.我有6个滑块可以调整每个通道的上限和下限.这些阈值用于对图像进行二值化(使用opencv inRange函数).
在那之后,我正在侵蚀和扩展二进制图像以消除噪声并联合nerby块(使用opencv erodedilate函数).
下一步是findContours在二进制图像中查找轮廓(使用opencv 函数).这些轮廓用于检测最小的方向矩形(使用opencv minAreaRect函数).作为最终结果,我正在使用面积最大的矩形.

该程序的简短结论:

  1. 抓住一个框架
  2. 将该帧转换为HSV
  3. 将其二值化(使用用户选择的颜色和滑块的阈值)
  4. 应用变形操作(侵蚀和扩张)
  5. 查找轮廓
  6. 获得每个轮廓最小的定向bouding盒
  7. 取结果中最大的边界框

您可能已经注意到,我没有利用有关纸张实际形状的知识,仅仅因为我不知道如何正确使用这些信息.

我也考虑过使用opencv的跟踪算法.但有三个原因使我无法使用它们:

  1. 比例不变性:据我读到的一些算法,有些不支持对象的不同比例.
  2. 运动预测:一些算法使用运动预测来获得更好的性能,但我跟踪的对象完全随机移动,因此无法预测.
  3. 简单:我只是在图像中寻找单色矩形,没有像汽车或人物跟踪那样花哨的东西.

这是一个 - 相对 - 好的捕获(侵蚀和扩张后的二进制图像) 好

这是一个糟糕的 坏

问题

如何提高检测效果,尤其是更能抵抗照明变化?

更新

以下是一些用于测试的原始图像.

你不能只使用更厚的材料吗?
是的,我可以而且我已经做过了(不幸的是我现在无法访问这些内容).但问题仍然存在.即使我使用像cartboard这样的材料.它不像纸一样容易弯曲,但仍然可以弯曲它.

你如何获得矩形的大小,旋转和位置?opencv
minAreaRect功能返回一个RotatedRect对象.该对象包含我需要的所有数据.

注意
由于矩形是单色的,因此无法区分顶部和底部或左右.这意味着旋转始终在[0, 180]我的目的范围内完全正常.矩形两边的比例总是如此w:h > 2:1.如果矩形是方形,则旋转范围将变为[0, 90],但这可以认为是无关紧要的.

正如评论中所建议的那样,我将尝试使用直方图均衡来减少亮度问题并查看ORB,SURF和SIFT.

我会更新进展情况.

c++ opencv image-processing object-detection

15
推荐指数
2
解决办法
8853
查看次数

MSVC constexpr函数'xyz'不能导致常量表达式

我已经创建了一个函数,它将多个较小的值连接成一个较大的值,同时保留值的bianry表示(例如,int argb从多个构建一个unsigned char r, g, b, a).我知道我也可以通过改变价值来实现这一点,但这不是这个问题的问题.

但是,如果我使用该函数实际从这些值生成一个整数,msvc会抛出编译器错误:

error C3615: constexpr function 'Color::operator int' cannot result in a constant expression
note: failure was caused by call of undefined function or one not declared 'constexpr'
note: see usage of '<lambda_dcb9c20fcc2050e56c066522a838749d>::operator ()'
Run Code Online (Sandbox Code Playgroud)

是一个完整的样本.Clang和gcc编译代码但msvc拒绝:

#include <type_traits>
#include <memory>

namespace detail
{
    template <typename From, typename To, size_t Size>
    union binary_fusion_helper
    {
        const From from[Size];
        const To to;
    };

    template <typename To, typename Arg, typename ...Args, typename = std::enable_if_t<(... …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ c++17

10
推荐指数
1
解决办法
1081
查看次数

多维数组、可为 null 的引用类型和类型转换

使用 C# 8 的可空引用类型,我们可以编写(对于引用类型):

T x = ...;
T? y = x;
Run Code Online (Sandbox Code Playgroud)

但是,我无法理解多维和锯齿状数组的转换规则。

string[][] a = new string[1][];
string?[]?[] b = new string[1][];
string?[]?[]? c = new string[1][];
string?[,][] d = new string[1,2][];
string?[,][]? e = new string[1,2][];
string?[,]?[] f = new string[1,2][];   // compiler error
Run Code Online (Sandbox Code Playgroud)

最后一个例子给了我

错误 CS0029:无法将类型 'string[ , ][]' 隐式转换为 'string?[ , ]?[]'

既然它适用于锯齿状数组(请参阅 参考资料b),为什么它不适用于多维数组呢?

R# 还告诉我

'c' 可以声明为不可空

string?[]?[]? c = new string[1][];
//          ^ redundant
Run Code Online (Sandbox Code Playgroud)

我知道编译器可以证明它c本身不为空,但我很困惑第三个?是多余的。鉴于锯齿状数组是从左到右创建的(即new int[2][]而不是 …

c# jagged-arrays multidimensional-array nullable-reference-types

9
推荐指数
1
解决办法
306
查看次数

gcc和clang抛出"没有匹配的函数调用",但msvc(cl)编译并按预期工作

我编写了一个小函数模板,它将新容器中的不同容器连接起来:

#include <vector>
#include <unordered_set>
#include <string>
#include <iostream>
#include <iterator>

namespace impl
{
    template <typename OutIterator, typename Container, typename ...Containers>
    void join(OutIterator iterator, const Container& container, const Containers& ...containers)
    {        
        for (const auto& item : container)
            *iterator++ = item;

        join(iterator, containers...);  // gcc and clang cannot resolve this call
    }

    template <typename OutIterator, typename Container>
    void join(OutIterator iterator, const Container& container)
    {        
        for (const auto& item : container)
            *iterator++ = item;
    }
}

template <typename OutContainer, typename ...Containers>
OutContainer …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang cl c++17

8
推荐指数
1
解决办法
285
查看次数

在 memcpy 缓冲区 UB 上使用 reinterpret_cast 吗?

鉴于代码

struct A {};

auto obj = new A;
std::vector<unsigned char> buffer;
buffer.resize(sizeof(obj));
std::memcpy(buffer.data(), &obj, sizeof(obj));  // this copies the pointer, not the object!

// ...

auto ptr = *reinterpret_cast<A**>(buffer.data()); // is this UB?
delete ptr;
Run Code Online (Sandbox Code Playgroud)

reinterpret_cast在这种情况下是使用UB 吗?我会说是的,因为memcpy没有开始实例的生命周期,因此违反了严格的别名规则(这就是为什么std::bit_cast被添加到 C++20)。

如果我用另一个memcpy(读取指针)替换强制转换,程序会被很好地定义吗?

c++ language-lawyer

8
推荐指数
1
解决办法
565
查看次数

意外的相等测试,Equals(a, a) 评估为 false

给定结构 S1:

unsafe readonly struct S1
{
    public readonly int A1, A2;
    public readonly int* B;

    public S1(int a1, int a2, int* b)
    {
        A1 = a1;
        A2 = a2;
        B = b;
    }
}
Run Code Online (Sandbox Code Playgroud)

和一个平等测试:

int x = 10;
var a = new S1(1, 2, &x);
var b = new S1(1, 2, &x);

var areEqual = Equals(a, b);  // true
Run Code Online (Sandbox Code Playgroud)

areEqual 正如预期的那样,评估为 true。

Now lets slightly change our struct to S2 (replacing the pointer with a string):

unsafe readonly …
Run Code Online (Sandbox Code Playgroud)

c#

8
推荐指数
1
解决办法
197
查看次数

为什么析构函数不能有引用限定符?

是否有理由(除了因为标准这么说)为什么不允许使用以下代码?

struct Foo
{
    ~Foo() && {}
    ~Foo() & {}
};
Run Code Online (Sandbox Code Playgroud)

我知道这是非法的,但我想知道为什么。

我在考虑避免未命名实例问题,即在使用保护对象时,例如:

void do_something()
{
    std::lock_guard{my_mutex};
    // some synchronized operation
}
Run Code Online (Sandbox Code Playgroud)

这是合法的代码,但显然很容易出错,因为锁保护会在构造后立即销毁,因为它是一个临时(未命名)对象。

我正打算做这样的事情

struct Foo
{
    ~Foo() && = delete;
    ~Foo() & = default;
};
Run Code Online (Sandbox Code Playgroud)

如果类型被构造为临时类型,则会出现编译器错误。

c++ destructor ref-qualifier

7
推荐指数
1
解决办法
123
查看次数

是否允许获取未定义函数的地址?

以下代码定义了整个程序。这个程序标准是否符合(最新版本)?

void foo();

int main()
{
    auto x = &foo;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是一个方便的快捷方式。

这段代码没有实际用途,我只是好奇。

c++ function-pointers one-definition-rule language-lawyer

6
推荐指数
1
解决办法
91
查看次数