ermig1979 / Simd

C++ image processing and machine learning library with using of SIMD: SSE, AVX, AVX-512, AMX for x86/x64, VMX(Altivec) and VSX(Power7) for PowerPC, NEON for ARM.
http://ermig1979.github.io/Simd
MIT License
2.03k stars 406 forks source link

Is this correct for IPlImage #207

Open HowToExpect opened 2 years ago

HowToExpect commented 2 years ago
long long getCurrentTimeMicro()
{
    return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}

void InnerMixtureImage(IplImage* pSrc, IplImage* pDst, int xpos, int ypos)
{
    if (!pSrc || !pDst)
        return;

    if (pSrc->nChannels != 4 || pDst->nChannels != 4)
        return;

    int w = xpos + pSrc->width;
    int h = ypos + pSrc->height;

    if (w > pDst->width || h > pDst->height)
    {
        printf("<WARNING> %s: src width = %d, height = %d, dst width = %d, height = %d, pos x = %d, y = %d\r\n",
            __FUNCTION__, pSrc->width, pSrc->height, pDst->width, pDst->height, xpos, ypos);
        return;
    }

    int i, j;
    for (j = 0; j < pSrc->height; ++j)
    {

        unsigned char* pucDst = (unsigned char*)pDst->imageData + (j + ypos) * pDst->widthStep + xpos * pDst->nChannels;
        unsigned char* pucSrc = (unsigned char*)pSrc->imageData + j * pSrc->widthStep;

        for (i = 0; i < pSrc->width; ++i)
        {
            unsigned char alpha = pucSrc[3];

            if (alpha == 0)
            {
            }
            else if (alpha == 255)
            {
                pucDst[0] = pucSrc[0];
                pucDst[1] = pucSrc[1];
                pucDst[2] = pucSrc[2];
                pucDst[3] = pucSrc[3];
            }
            else 
            {
                pucDst[0] = (pucDst[0] * (255 - alpha) + pucSrc[0] * alpha) >> 8;
                pucDst[1] = (pucDst[1] * (255 - alpha) + pucSrc[1] * alpha) >> 8;
                pucDst[2] = (pucDst[2] * (255 - alpha) + pucSrc[2] * alpha) >> 8;
                pucDst[3] = pucDst[3] > alpha ? pucDst[3] : alpha;
            }
            pucDst += 4;
            pucSrc += 4;
        }
    }

}

int main()
{
    typedef Simd::View<Simd::Allocator> View;

    IplImage* pUpdate = cvLoadImage("update.png", CV_LOAD_IMAGE_UNCHANGED);

    int width = pUpdate->width;
    int height = pUpdate->height;
    int stride = pUpdate->widthStep;

    IplImage* pImg = cvCreateImage(cvGetSize(pUpdate), 8, 4);
    cvSet(pImg, cvScalar(51, 51, 51, 255));

    IplImage* pChannel1 = cvCreateImage(cvGetSize(pUpdate), 8, 1);
    IplImage* pChannel2 = cvCreateImage(cvGetSize(pUpdate), 8, 1);
    IplImage* pChannel3 = cvCreateImage(cvGetSize(pUpdate), 8, 1);
    IplImage* pChannel4 = cvCreateImage(cvGetSize(pUpdate), 8, 1);

    cvSplit(pUpdate, pChannel1, pChannel2, pChannel3, pChannel4);

    View src(width, height, stride, View::Bgra32, pImg->imageData);

    View dst(width, height, stride, View::Bgra32, pUpdate->imageData);

    View alpha(pChannel4->width, pChannel4->height, pChannel4->widthStep, View::Gray8, pChannel4->imageData);

    int64_t start = getCurrentTimeMicro();

    Simd::AlphaBlending(dst, alpha, src);

    int64_t end = getCurrentTimeMicro();

    cout << "Simd::AlphaBlending elapsed time = " << (end - start) << " us " << endl;

    start = getCurrentTimeMicro();

    //InnerMixtureImage(pUpdate, pImg, 0, 0);

    end = getCurrentTimeMicro();

    cout << "InnerMixtureImage elapsed time = " << (end - start) << " us " << endl;

    cvShowImage("blend", pImg);
    cvWaitKey();
}