OpenCV:在iOS中带透明度的图像覆盖时,随机出现alpha通道伪影

3
在我的iOS项目中,我正在将带有alpha通道的小PNG图像作为叠加层添加到JPEG图片上。在DEBUG模式下,我的设备上的结果与预期相同,泪痕被正确绘制。

iOS Result DEBUG mode

当我在模拟器上运行相同的代码或以发布模式归档和导出应用程序时,Alpha通道中会出现随机伪影。

iOS Result on Simulator and RELEASE mode

底层的cv::Mat都包含头信息和有效的数据部分。即使在绿色背景下,错误也是可重现的。

enter image description here

这种行为似乎完全是随机的,因为有时不会绘制任何工件(图像3:右眼泪,图像4:左眼泪)。 在此输入图像描述 有什么想法吗?

展示你的代码。通常情况下,如果代码在DEBUG模式下可以运行但在RELEASE模式下无法运行,那么很可能是由于未初始化的数据所导致的。 - cxyzs7
你可能会对我的博客中关于alpha通道方法的背景信息感兴趣。我建议你首先使用已知可行的方法。例如,OpenCV使用与本机iOS应用程序不同的图像加载方法。http://www.modejong.com/blog/post18_green_screen - MoDJ
1个回答

0
const char *cpath1 = [@"" cStringUsingEncoding:NSUTF8StringEncoding];//overlay image path , within @"" pass your image path which is in NSString

const char *cpath  = [@"" cStringUsingEncoding:NSUTF8StringEncoding];//underlay imagepath

    cv::Mat overlay = cv::imread(cpath1,-1);//-1 is for read .png images
    cv::Mat underlay = cv::imread(cpath,-1);

    //convert mat image in to RGB channel
    cv::Mat overlayAlpha;
    std::vector<Mat> channels1;
    split(overlay, channels1);
    channels1[3].copyTo(overlayAlpha);

    cv::Mat underlayAlpha;
    std::vector<Mat> channels2;
    split(underlay, channels2);
    channels2[3].copyTo(underlayAlpha);

    overlayImage( &underlay, &overlay,cv::Point(10,10);

    convert final image to RGB channel
    cv::split(underlay,channels1);

    std::swap(channels1[0],channels1[2]);// swap B and R channels.
    cv::merge(channels1,underlay);//merge channels

    MatToUIImage(background); //display your final image, it returns cv::Mat image

覆盖函数的实现如下:

参考自:http://answers.opencv.org/question/73016/how-to-overlay-an-png-image-with-alpha-channel-to-another-png/

void overlayImage(Mat* src, Mat* overlay, const cv::Point& location){

for (int y = max(location.y, 0); y < src->rows; ++y)
{
    int fY = y - location.y;

    if (fY >= overlay->rows)
        break;

    for (int x = max(location.x, 0); x < src->cols; ++x)
    {
        int fX = x - location.x;

        if (fX >= overlay->cols)
            break;

        double opacity = ((double)overlay->data[fY * overlay->step + fX * overlay->channels() + 3]) / 255;

        for (int c = 0; opacity > 0 && c < src->channels(); ++c)
        {
            unsigned char overlayPx = overlay->data[fY * overlay->step + fX * overlay->channels() + c];
            unsigned char srcPx = src->data[y * src->step + x * src->channels() + c];
            src->data[y * src->step + src->channels() * x + c] = srcPx * (1. - opacity) + overlayPx * opacity;
        }
    }
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接