5

我目前正在将一些 OpenCV 代码从 C++ 转换为 Java。我不能使用 JavaCV,因为我们需要在本机 Java 中进行转换,而不是 JNA。在代码中的某一时刻,我得到以下任务:

dst[x] = (uchar)(-(kHit >= kForeground));

哪里dstuchar*kHit并且kForegroundints。

我一直找不到任何关于它是如何工作的,Java 不会将它识别为一个操作。在代码中的另一点对这两个变量进行了操作,它存储两个值之一:255 或 0。

有问题的代码来自opencv/video/src/bgfg_gaussmix.cpp.

4

4 回答 4

7

在 C++ 中,布尔表达式产生两个值之一 -01. 当您将一元减号-应用于结果时,您会得到0-1。当你重新解释-1uchar时,你得到255.

您可以使用条件将此表达式转换为 Java:

dst[x] = (kHit >= kForeground) ? 255 : 0;

由于分支,它不会像原来的那样快。但是,您对它的速度几乎无能为力,因为 Java 缺乏将布尔值重新解释为数字的能力。

于 2012-07-18T14:47:16.253 回答
6

kHit >= kForeground返回trueor false,这在 C++ 中意味着1or 0。前面的减号将其转换为-1or 0。强制转换为uchar( (uchar)) 返回0for并为否定0换行 to 。255-1

在 Konrad 的评论之后,我也怀疑这是否定义明确。它定义明确,但就可读性而言,它仍然是一段糟糕的代码。:)

于 2012-07-18T14:47:06.213 回答
1

它的基本作用如下:

kHit >= kForeground

是 bool 类型的表达式

-(kHit >= kForeground)

将此 bool 转换为 int (基于true==1and false==0)并将其取反,结果为true==-1and false==0

然后将其转换为 a uchar,从而得到-1==255and 0==0

必须注意的是,虽然看起来使用了数字的底层实现细节,但所有这些转换都由 C++ 和 C 标准保证,因为负无符号数被指定为根据二进制补码运行。

但是如果 Java 不支持这一点,你总是可以用条件赋值来替换它:

dst[x] = (kHit>=kForeground) ? 255 : 0;
于 2012-07-18T14:53:21.677 回答
1

该表达式(kHit >= kForeground)产生一个具有值true或的布尔值false。当应用一元-时,bool被提升为int,并且转换产生1fortrue0for false。升级后,符号变为-10,然后uchar由外部演员转换为。

请注意,重要的信息是一元operator-不应用于布尔值,但布尔值被转换int为然后应用。这可以用一些模板魔法来测试:

template <typename T, typename U>
struct same_type {
    static const bool value = false;
};
template <typename T>
struct same_type<T,T> {
    static const bool value = true;
};
template <typename T>
void f( T value ) {
    std::cout << "Is int? " << std::boolalpha << same_type<T, int>::value << "\n";
    std::cout << "Is bool? " << same_type<T, bool>::value << "\n";
}
int main() {
    f(-true);
}

模板通过使用上面的f模板来测试传递参数的类型int(简单到足以理解)。如果我们调用模板作为参数类型推导将设置为表达式的类型。如果您运行该程序,您将看到它打印出.boolsame_typef-trueT-trueIs int? true\nIs bool? false

于 2012-07-18T15:25:28.107 回答