我目前正在将一些OpenCV代码从C ++转换为Java。我不能使用JavaCV,因为我们需要在本机Java中进行转换,而不是JNA。在代码中的某一点,我得到以下任务:
dst[x] = (uchar)(-(kHit >= kForeground));
其中dst
为uchar*
,kHit
和kForeground
为int
。
我一直无法找到有关其工作原理的任何信息,Java也不会将其识别为操作。在代码中的另一个点上对这两个变量进行了操作,它存储了两个值中的一个:255或0.
相关代码来自opencv/video/src/bgfg_gaussmix.cpp
。
答案 0 :(得分:7)
在C ++中,布尔表达式产生两个值之一 - 0
或1
。将一元减去-
应用于结果后,您会获得0
或-1
。当您将-1
重新解释为uchar
时,您会获得255
。
您可以使用条件将此表达式转换为Java:
dst[x] = (kHit >= kForeground) ? 255 : 0;
由于分支,它不会像原始分支一样快。然而,由于Java缺乏将布尔值重新解释为数值的能力,因此无法对它的速度做些什么。
答案 1 :(得分:6)
kHit >= kForeground
会返回true
或false
,这在C ++中的含义是1
或0
。前面的减号会将其转换为-1
或0
。转化为uchar
((uchar)
)会为0
返回0
,并为255
包围-1
。
根据Konrad的评论,我也很怀疑这个定义得很好。它定义明确,但就可读性而言,它仍然是一段糟糕的代码。 :)
答案 2 :(得分:1)
它基本上做的是:
kHit >= kForeground
是bool类型的表达式
-(kHit >= kForeground)
将此bool转换为int(基于true==1
和false==0
)并取消它,从而产生true==-1
和false==0
。
然后将其转换为uchar
,结果为-1==255
和0==0
。
必须注意的是,尽管看起来使用数字的底层实现细节,但所有这些转换都由C ++和C标准保证,因为负无符号数被指定为根据二进制补码运行。
但是如果Java不支持这一点,你总是可以通过条件赋值来替换它:
dst[x] = (kHit>=kForeground) ? 255 : 0;
答案 3 :(得分:1)
表达式(kHit >= kForeground)
产生一个值为true
或false
的布尔值。应用一元-
后,bool
会升级为int
,转化结果为1
true
或0
{} {1}}。促销后,该代码会更改为false
或-1
,然后由外部演员转换为0
。
请注意,重要的信息是,一元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
和bool
传递的参数的类型。如果我们使用same_type
作为参数类型调用f
模板,则会将-true
设置为T
的表达式类型。如果您运行该程序,您将看到它打印-true
。