我的代码在Visual Studio中使用OpenCV。但它没有在Android NDK
应用程序中显示输出,并且没有显示错误
以下是我的代码。
void sow(Mat& img1, Mat& img2, Mat& out)
{
Mat result(img1.size(), CV_32FC4);
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
for (int i = 0; i < img1.size().height; ++i){
for (int j = 0; j < img1.size().width; ++j){
for (int c = 0; c<img1.channels(); c++){ // Iterate through colors
//Formula
float target = (float)img1.at<uchar>(i, 4 * j + c) / 255.;
float blend = (float)img2.at<uchar>(i, 4 * j + c) / 255.;
if (blend > 0.5){
result.at<float>(i, 4 * j + c) = ((1 - (1 - target) * (1 - 2 * (blend - 0.5))));
}
else{
result.at<float>(i, 4 * j + c) = (target * (2 * blend));
}
}
}
}
result.convertTo(out, CV_8UC4, 255);
}
它适用于带有8UC3
图像的Visual Studio,但不适用于Android中的8UC4
图像。除了imageview中的n输出外,没有错误。
当我更改公式时,同样适用于我的Android,但这个公式适用于Visual Studio。当我有相同的代码但
中的公式不同时,有些图像适合我if (blend > 0.5)
{
result.at<float>(i, 4 * j + c) = ((1 - (1 - target) * (1 - 2 * (blend - 0.5))));
}
else
{
result.at<float>(i, 4 * j + c) = (target * (2 * blend));
}
他们正在显示输出。
我使用的方式相同:
void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
max(img1, img2, out);
}
它显示输出但是当我在同一代码中使用max(img1, img2, out);
时它没有显示输出。他们都在Visual Studio中工作,但在使用NDK的Android中工作。我测试了我的JNI
并且它工作正常,Java代码也是正确的。
输入图片:
结果后的结果图片:
答案 0 :(得分:2)
第1部分
我认为您的问题是在此行中将alpha设置为0
(透明):
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
将其更改为
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
由于唯一的区别是alpha通道,这是第一个看的地方。如果img1或img2的0都是0,那么你的结果将是完全透明的!
根据{{3}},建议的处理方法是
result.alpha = 1 - (1 - target.alpha) * (1 - blend.alpha)
试试这个:
void sow(Mat& img1, Mat& img2, Mat& out)
{
Mat result(img1.size(), CV_32FC4);
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
for (int i = 0; i < img1.rows; ++i)
{
Vec4b* i1 = img1.ptr<Vec4b>(i);
Vec4b* i2 = img2.ptr<Vec4b>(i);
Vec4f* r = result.ptr<Vec4f>(i);
for (int j = 0; j < img1.cols; ++j)
{
Vec4b p1 = i1[j];
Vec4b p2 = i2[j];
Vec4f& pr = r[j];
// Blend overlay color channels
for (int c = 0; c < 3; ++c)
{
//Formula
float target = (float) p1[c] / 255.0f;
float blend = (float) p2[c] / 255.0f;
if (blend > 0.5)
{
pr[c] = 1 - (1 - target) * (1 - 2 * (blend - 0.5f));
}
else
{
pr[c] = target * 2 * blend;
}
}
// Alpha channel
float target_alpha = (float) p1[3] / 255.0f;
float blend_alpha = (float) p2[3] / 255.0f;
pr[3] = 1 - (1 - target_alpha) * (1 - blend_alpha);
}
}
result.convertTo(out, CV_8UC4, 255);
}
使用输入图像,可以生成所需的结果:
此外,问题可能在于您的JNI代码,请检查调用sow()
的代码是否正常工作,只需返回img1
&amp; img2
:
void sow(Mat& img1, Mat& img2, Mat& out)
{
img1.copyTo(out);
}
顺便说一句,除了img2
之外,这些席子上的参考调用是多余的。 E.g。
void sow(Mat img1, Mat& img2, Mat out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
img2.copyTo(out);
}
第2部分
的原因void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
min(img1, img2, out);
}
不显示任何内容out
中的Alpha通道始终设置为0
(完全透明)。在img2中将alpha更改为255,它应该可以工作:
void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
min(img1, img2, out);
}