Issue
My code works in Visual Studio using OpenCV. But its not showing output in an Android NDK application, and its not showing an error
Below is my code.
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);
}
It works for me in Visual Studio with an 8UC3 image, but not with an 8UC4 image in Android. Other than n output in imageview, there is no error.
The same thing works for me in Android when I change the formula, but this formula works for me on Visual Studio . Some images work for me when I have the same code but different formula's in
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));
}
And they are showing output.
In the same way when I use :
void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
max(img1, img2, out);
}
it shows output but when I use max(img1, img2, out); in the same code its not showing output. And they all are working in Visual Studio but not in Android using NDK. I tested my JNI and it is work correctly, the Java code is correct too.
input image :

Resultant image after result :

Solution
Part 1
I think your problem is setting alpha to 0 (transparent) in this line:
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
Change it to
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
Since the only difference is the alpha channel, that is the first place to look. If either img1 or img2 has 0 alpha your result will be completely transparent!
The suggested way to handle this, according to this question, is
result.alpha = 1 - (1 - target.alpha) * (1 - blend.alpha)
Try this:
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);
}
With your input image this generates your desired result:

Also, the problem might be with your JNI code, check that the code calling sow() works correctly, just return img1 & img2:
void sow(Mat& img1, Mat& img2, Mat& out)
{
img1.copyTo(out);
}
BTW, except for img2 the call by reference on those Mats is superfluous. E.g.
void sow(Mat img1, Mat& img2, Mat out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
img2.copyTo(out);
}
Part 2 The reason that
void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 0));
min(img1, img2, out);
}
doesn't display anything is that the alpha channel in out is always set to 0 (completely transparent). Change the alpha to 255 in img2 and it should work:
void BL(Mat& img1, Mat& img2, Mat& out)
{
img2 = Mat(img1.size(), img1.type(), Scalar(186, 44, 28, 255));
min(img1, img2, out);
}
Answered By - Bull
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.