For people working in computer vision, openCv is godsend. The following is code implementation for creating an optical illusion. This involves creating a pencil sketch and some more simple filtering application. Check out the illusion here.
Direct Access Header: It makes accessing individual pixels in openCv way easier

  1. #ifndef DACCESS_H
  2. #define DACCESS_H
  3.  
  4. //Wrapper class to access openCV pixel values in a easier way
  5.  
  6. template class Image
  7. {
  8. private:
  9. IplImage* imgp;
  10. public:
  11. Image(IplImage* img=0) {imgp=img;}
  12. ~Image(){imgp=0;}
  13. void operator=(IplImage* img) {imgp=img;}
  14. inline T* operator[](const int rowIndx) {
  15. return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
  16. };
  17.  
  18. typedef struct{
  19. unsigned char b,g,r;
  20. } RgbPixel;
  21.  
  22. typedef struct{
  23. float b,g,r;
  24. } RgbPixelFloat;
  25.  
  26. typedef Image RgbImage;
  27. typedef Image RgbImageFloat;
  28. typedef Image BwImage;
  29. typedef Image BwImageFloat;
  30.  
  31. #endif

operation.h Blending operations made easy

  1. #define ChannelBlend_Normal(A) ((unsigned char)(A))
  2. #define ChannelBlend_Invert(A) ((unsigned char)(255-A))
  3. #define ChannelBlend_Lighten(A,B) ((unsigned char)((B > A) ? B:A))
  4. #define ChannelBlend_Darken(A,B) ((unsigned char)((B > A) ? A:B))
  5. #define ChannelBlend_Multiply(A,B) ((unsigned char)((A * B) / 255))
  6. #define ChannelBlend_Average(A,B) ((unsigned char)((A + B) / 2))
  7. #define ChannelBlend_Add(A,B) ((unsigned char)(min(255, (A + B))))
  8. #define ChannelBlend_Subtract(A,B) ((unsigned char)((A + B < 255) ? 0:(A + B - 255)))
  9. #define ChannelBlend_Difference(A,B) ((unsigned char)(abs(A - B)))
  10. #define ChannelBlend_Negation(A,B) ((unsigned char)(255 - abs(255 - A - B)))
  11. #define ChannelBlend_Screen(A,B) ((unsigned char)(255 - (((255 - A) * (255 - B)) >> 8)))
  12. #define ChannelBlend_Exclusion(A,B) ((unsigned char)(A + B - 2 * A * B / 255))
  13. #define ChannelBlend_Overlay(A,B) ((unsigned char)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255)))
  14. #define ChannelBlend_SoftLight(A,B) ((unsigned char)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))
  15. #define ChannelBlend_HardLight(A,B) (ChannelBlend_Overlay(B,A))
  16. #define ChannelBlend_ColorDodge(A,B) ((unsigned char)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B)))))
  17. #define ChannelBlend_ColorBurn(A,B) ((unsigned char)((B == 0) ? B:max(0, (255 - ((255 - A) << 8 ) / B))))
  18. #define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))
  19. #define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B))
  20. #define ChannelBlend_LinearLight(A,B)((unsigned char)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128))))
  21. #define ChannelBlend_VividLight(A,B) ((unsigned char)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128))))
  22. #define ChannelBlend_PinLight(A,B) ((unsigned char)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128))))
  23. #define ChannelBlend_HardMix(A,B) ((unsigned char)((ChannelBlend_VividLight(A,B) < 128) ? 0:255))
  24. #define ChannelBlend_Reflect(A,B) ((unsigned char)((B == 255) ? B:min(255, (A * A / (255 - B)))))
  25. #define ChannelBlend_Glow(A,B) (ChannelBlend_Reflect(B,A))
  26. #define ChannelBlend_Phoenix(A,B) ((unsigned char)(min(A,B) - max(A,B) + 255))
  27. #define ChannelBlend_Alpha(A,B,O) ((unsigned char)(O * A + (1 - O) * B))
  28. #define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_Alpha(F(A,B),A,O))

Now the main code

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include "dAccess.h"
  7. #include "operations.h"
  8.  
  9. //Parameters
  10. #define SIGMA1 3.0
  11. #define SIGMA2 6.0
  12. #define LINEWIDTH 4
  13.  
  14. using namespace std;
  15.  
  16. int main(int argc, char *argv[])
  17. {
  18. //original image
  19. IplImage* usrImg = NULL;
  20. //Resized image
  21. IplImage *img = NULL;
  22. //grayscale versions
  23. IplImage* gimg1 = NULL;
  24. IplImage* gimg2 = NULL;
  25.  
  26. //Initialize fonts
  27. CvFont font;
  28. cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0,1.0);
  29.  
  30. if(argcwidth/usrImg->height;
  31.  
  32. if(usrImg->width height width height width,usrImg->height),usrImg->depth, usrImg->nChannels);
  33. else if(targetAspect > sourceAspect)
  34. img = cvCreateImage(cvSize((int)(800*sourceAspect),600),usrImg->depth, usrImg->nChannels);
  35. else
  36. img = cvCreateImage(cvSize(800,(int)(600/sourceAspect)),usrImg->depth, usrImg->nChannels);
  37.  
  38. cvResize(usrImg,img);
  39. cvReleaseImage(&usrImg);
  40.  
  41. //Convert to pencil art--------------------------------------------------------------------------
  42. //Convert to grayscale
  43. gimg1 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);
  44. cvCvtColor(img,gimg1,CV_BGR2GRAY);
  45.  
  46. //Make a copy
  47. gimg2 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);
  48. cvCopy(gimg1,gimg2);
  49. //Create direct access to pixel values
  50. BwImage gimg1Daccess(gimg1);
  51. BwImage gimg2Daccess(gimg2);
  52.  
  53. //Apply Gaussian filter
  54. cvSmooth(gimg2,gimg2,CV_GAUSSIAN,0,0,SIGMA1);
  55. //Invert it; gimp2 = 1-gimp2;
  56. for(int i=0;iheight;i++)
  57. for(int j=0;jwidth;j++)
  58. gimg2Daccess[i][j] = ChannelBlend_Invert(gimg2Daccess[i][j]);
  59. //Merge at 50% opacity; gimg1 = 0.5*gimg1 + 0.5*gimg2;
  60. for(int i=0;iheight;i++)
  61. for(int j=0;jwidth;j++)
  62. gimg1Daccess[i][j] = ChannelBlend_Alpha(gimg1Daccess[i][j],gimg2Daccess[i][j],0.5);
  63.  
  64. //Color Dodge gimg1 by itself
  65. for(int i=0;iheight;i++)
  66. for(int j=0;jwidth;j++)
  67. gimg1Daccess[i][j] = ChannelBlend_ColorDodge(gimg1Daccess[i][j],gimg1Daccess[i][j]);
  68. //Done
  69. //Create a grid of lines------------------------------------------------------------------------
  70. for(int i=0;iheight;i++)
  71. for(int j=0;jwidth;j++)
  72. if(i > img->height - WATERMARK_H || ((int)(j/LINEWIDTH))%2 == 0)
  73. gimg2Daccess[i][j] = 255;
  74. else
  75. gimg2Daccess[i][j] = 0;
  76. //Gaussian blur gimg1
  77. cvSmooth(gimg1,gimg1,CV_GAUSSIAN,0,0,SIGMA2);
  78. //Overlay both images
  79. for(int i=0;iheight;i++)
  80. for(int j=0;jwidth;j++)
  81. gimg1Daccess[i][j] = ChannelBlend_Multiply(gimg1Daccess[i][j],gimg2Daccess[i][j]);
  82.  
  83. //Save the image
  84. cvSaveImage("illusion.png",gimg1);
  85.  
  86. system("illusion.htm");
  87.  
  88. // wait for a key
  89. cout<
Related Posts Plugin for WordPress, Blogger... Print This Post Print This Post
Tagged with:  

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...

Archives