alphaBlend.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // alphaBlend.cpp
  3. //
  4. //
  5. // Created by Sunita Nayak on 3/14/17.
  6. //
  7. //
  8. #include <opencv2/opencv.hpp>
  9. using namespace cv;
  10. using namespace std;
  11. // Alpha blending using multiply and add functions
  12. Mat& blend(Mat& alpha, Mat& foreground, Mat& background, Mat& outImage)
  13. {
  14. Mat fore, back;
  15. multiply(alpha, foreground, fore);
  16. multiply(Scalar::all(1.0)-alpha, background, back);
  17. add(fore, back, outImage);
  18. return outImage;
  19. }
  20. // Alpha Blending using direct pointer access
  21. Mat& alphaBlendDirectAccess(Mat& alpha, Mat& foreground, Mat& background, Mat& outImage)
  22. {
  23. int numberOfPixels = foreground.rows * foreground.cols * foreground.channels();
  24. float* fptr = reinterpret_cast<float*>(foreground.data);
  25. float* bptr = reinterpret_cast<float*>(background.data);
  26. float* aptr = reinterpret_cast<float*>(alpha.data);
  27. float* outImagePtr = reinterpret_cast<float*>(outImage.data);
  28. int i,j;
  29. for ( j = 0; j < numberOfPixels; ++j, outImagePtr++, fptr++, aptr++, bptr++)
  30. {
  31. *outImagePtr = (*fptr)*(*aptr) + (*bptr)*(1 - *aptr);
  32. }
  33. return outImage;
  34. }
  35. int main(int argc, char** argv)
  36. {
  37. // Read in the png foreground asset file that contains both rgb and alpha information
  38. Mat foreGroundImage = imread("foreGroundAssetLarge.png", -1);
  39. Mat bgra[4];
  40. split(foreGroundImage, bgra);//split png foreground
  41. // Save the foregroung RGB content into a single Mat
  42. vector<Mat> foregroundChannels;
  43. foregroundChannels.push_back(bgra[0]);
  44. foregroundChannels.push_back(bgra[1]);
  45. foregroundChannels.push_back(bgra[2]);
  46. Mat foreground = Mat::zeros(foreGroundImage.size(), CV_8UC3);
  47. merge(foregroundChannels, foreground);
  48. // Save the alpha information into a single Mat
  49. vector<Mat> alphaChannels;
  50. alphaChannels.push_back(bgra[3]);
  51. alphaChannels.push_back(bgra[3]);
  52. alphaChannels.push_back(bgra[3]);
  53. Mat alpha = Mat::zeros(foreGroundImage.size(), CV_8UC3);
  54. merge(alphaChannels, alpha);
  55. // Read background image
  56. Mat background = imread("backGroundLarge.jpg");
  57. // Convert Mat to float data type
  58. foreground.convertTo(foreground, CV_32FC3);
  59. background.convertTo(background, CV_32FC3);
  60. alpha.convertTo(alpha, CV_32FC3, 1.0/255); // keeps the alpha values betwen 0 and 1
  61. // Number of iterations to average the performane over
  62. int numOfIterations = 1; //1000;
  63. // Alpha blending using functions multiply and add
  64. Mat outImage= Mat::zeros(foreground.size(), foreground.type());
  65. double t = (double)getTickCount();
  66. for (int i=0; i<numOfIterations; i++) {
  67. outImage = blend(alpha, foreground, background, outImage);
  68. }
  69. t = ((double)getTickCount() - t)/getTickFrequency();
  70. cout << "Time for alpha blending using multiply & add function : " << t*1000/numOfIterations << " milliseconds" << endl;
  71. // Alpha blending using direct Mat access with for loop
  72. outImage = Mat::zeros(foreground.size(), foreground.type());
  73. t = (double)getTickCount();
  74. for (int i=0; i<numOfIterations; i++) {
  75. outImage = alphaBlendDirectAccess(alpha, foreground, background, outImage);
  76. }
  77. t = ((double)getTickCount() - t)/getTickFrequency();
  78. cout << "Time for alpha blending using alphaBlendDirectAccess : " << t*1000/numOfIterations << " milliseconds" << endl;
  79. //imshow("alpha blended image", outImage/255);
  80. //waitKey(0);
  81. return 0;
  82. }