Hi I used ippiInpaint_8u_C3R with IPP_INPAINT_TELEA flag and the result has a bug:
Input image contains Scalar=(77,88,99) and the 3X3 "dirt" has the scalar (33,17,2).
After using ippiInpaint_8u_C3R with IPP_INPAINT_TELEA flag,
the "clean" result has the scalar (77,77,77) instead of (77,88,99).
When using it with IPP_INPAINT_NS it works fine.
See the code below:
#include "opencv2/opencv.hpp" #include "ipp.h" Ipp32f *pFMDist = NULL; /* Pointer to distances image */ int fmDistStep = 0; /* Step, in bytes, through the distances image */ Ipp8u *pFMBuffer = NULL; /* Pointer to the Fast marching work buffer */ int fmBufferSize = 0; int state_size = 0, buf_size = 0; IppiSize mask_size; cv::Mat1b mask(64,64); cv::Mat3b img_to_clean(64, 64); cv::Mat3b out_img(64,64); int left = 22, top = 33, width = 3, height = 3; cv::Rect dirtRect(left, top, width, height); mask.setTo(0); mask(dirtRect).setTo(255); out_img.setTo(cv::Scalar(0,0,0)); img_to_clean.setTo(cv::Scalar(77,88,99)); img_to_clean(dirtRect).setTo(cv::Scalar(33,17,2)); mask_size.width = mask.cols; mask_size.height= mask.rows; pFMDist = ippiMalloc_32f_C1(mask_size.width, mask_size.height, &fmDistStep); int ippstatus = ippiFastMarchingGetBufferSize_8u32f_C1R(mask_size, &fmBufferSize); pFMBuffer = ippsMalloc_8u(fmBufferSize); IppStatus ipp_status = ippiFastMarching_8u32f_C1R(mask.data, mask.rows, pFMDist, fmDistStep, mask_size, (float) 6, pFMBuffer); IppiInpaintFlag flag = IPP_INPAINT_TELEA; IppStatus ipp_status2 = ippiInpaintGetSize(mask.data, mask.cols, mask_size, (float) 6, flag, 3, &state_size, &buf_size); Ipp8u* inpStateBuff = ippsMalloc_8u(state_size); Ipp8u* ipp_working_buffer = ippsMalloc_8u(buf_size); IppiInpaintState_8u_C1R *pInpState = nullptr; cv::Mat dist_map = cv::Mat(mask_size.height, mask_size.width, CV_32FC1, pFMDist); IppStatus ipp_status3= ippiInpaintInit_8u_C3R(&pInpState,pFMDist, fmDistStep, mask.data, mask.cols, mask_size, (float) 6, flag, inpStateBuff, ipp_working_buffer); ippsFree(pFMBuffer); ippsFree(pFMDist); IppStatus res = ippiInpaint_8u_C3R(img_to_clean.data, 3 * img_to_clean.cols, out_img.data, 3 * out_img.cols, mask_size, pInpState, ipp_working_buffer); ippsFree(inpStateBuff); ippsFree(ipp_working_buffer);
I used your program, but I could not reproduce your problem. The scalar I get is always (77,88,99). Could you please more information about your system environment. I used following code to get scalar, if you do similar way to access?
cv::Scalar result; mean=cv::mean(out_img); std::cout<<"Scalar("<<result<<", "<<result<<", "<<result<<")"<<std::endl;
Thank you for your reply.
You did reproduce the bug.
1. Please add the following to your code to see it:
cv::Scalar res_after_clean_on_dirt = out_img.at<cv::Vec3b>(top, left); std::cout<<"should be (77,88,99) but get Scalar("<<res_after_clean_on_dirt<<", "<<res_after_clean_on_dirt<<", "<<res_after_clean_on_dirt<<")"<<std::endl;
You will get (77,77,77)
2. You got average pixel values of 77,87.9758, 98,9517.
My sample code uses 64*64 image with mask of size 3X3.
I argue that ippInpaint returned 77 to all channels.
So lets look on the green (middle) value, I argue that the 3X3 area got value of 77 instead of 88:
((64*64 -3*3) * 88 + 77 * 3*3) / (64*64) = 87.9758.
((64*64-3*3)*99 + 77 * 3*3) / (64*64) = 98.9517
This issue has been submitted to developer team already, they are currently during the checking and fixing. If this problem has been make sure and developer team find any solution to fix, they will going to tell me. Once I get reply I will update here. Sorry for let you waiting, hope you could understand. Thank you.
On 22 Sep 2016 you reproduced the bug i reported (ippiInpaint_8u_C3R with IPP_INPAINT_TELEA)
Can you estimate if and when (date or ipp version) this bug will fixed?