qimage_blur.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2014 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #include <iostream>
  11. #include <algorithm>
  12. #include <QtGlobal>
  13. #if QT_VERSION >= 0x050000
  14. #include <QtWidgets>
  15. #else
  16. #include <QtGui>
  17. #endif
  18. #ifndef Q_MOC_RUN
  19. #include <boost/compute/system.hpp>
  20. #include <boost/compute/image/image2d.hpp>
  21. #include <boost/compute/interop/qt.hpp>
  22. #include <boost/compute/utility/dim.hpp>
  23. #include <boost/compute/utility/source.hpp>
  24. #endif // Q_MOC_RUN
  25. namespace compute = boost::compute;
  26. inline void box_filter_image(const compute::image2d &input,
  27. compute::image2d &output,
  28. compute::uint_ box_height,
  29. compute::uint_ box_width,
  30. compute::command_queue &queue)
  31. {
  32. using compute::dim;
  33. const compute::context &context = queue.get_context();
  34. // simple box filter kernel source
  35. const char source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
  36. __kernel void box_filter(__read_only image2d_t input,
  37. __write_only image2d_t output,
  38. uint box_height,
  39. uint box_width)
  40. {
  41. int x = get_global_id(0);
  42. int y = get_global_id(1);
  43. int h = get_image_height(input);
  44. int w = get_image_width(input);
  45. int k = box_width;
  46. int l = box_height;
  47. if(x < k/2 || y < l/2 || x >= w-(k/2) || y >= h-(l/2)){
  48. write_imagef(output, (int2)(x, y), (float4)(0, 0, 0, 1));
  49. }
  50. else {
  51. const sampler_t sampler = CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
  52. float4 sum = { 0, 0, 0, 0 };
  53. for(int i = 0; i < k; i++){
  54. for(int j = 0; j < l; j++){
  55. sum += read_imagef(input, sampler, (int2)(x+i-k, y+j-l));
  56. }
  57. }
  58. sum /= (float) k * l;
  59. float4 value = (float4)( sum.x, sum.y, sum.z, 1.f );
  60. write_imagef(output, (int2)(x, y), value);
  61. }
  62. }
  63. );
  64. // build box filter program
  65. compute::program program =
  66. compute::program::create_with_source(source, context);
  67. program.build();
  68. // setup box filter kernel
  69. compute::kernel kernel(program, "box_filter");
  70. kernel.set_arg(0, input);
  71. kernel.set_arg(1, output);
  72. kernel.set_arg(2, box_height);
  73. kernel.set_arg(3, box_width);
  74. // execute the box filter kernel
  75. queue.enqueue_nd_range_kernel(kernel, dim(0, 0), input.size(), dim(1, 1));
  76. }
  77. // this example shows how to load an image using Qt, apply a simple
  78. // box blur filter, and then display it in a Qt window.
  79. int main(int argc, char *argv[])
  80. {
  81. QApplication app(argc, argv);
  82. // check command line
  83. if(argc < 2){
  84. std::cout << "usage: qimage_blur [FILENAME]" << std::endl;
  85. return -1;
  86. }
  87. // load image using Qt
  88. QString fileName = argv[1];
  89. QImage qimage(fileName);
  90. size_t height = qimage.height();
  91. size_t width = qimage.width();
  92. size_t bytes_per_line = qimage.bytesPerLine();
  93. qDebug() << "height:" << height
  94. << "width:" << width
  95. << "bytes per line:" << bytes_per_line
  96. << "depth:" << qimage.depth()
  97. << "format:" << qimage.format();
  98. // create compute context
  99. compute::device gpu = compute::system::default_device();
  100. compute::context context(gpu);
  101. compute::command_queue queue(context, gpu);
  102. std::cout << "device: " << gpu.name() << std::endl;
  103. // get the opencl image format for the qimage
  104. compute::image_format format =
  105. compute::qt_qimage_format_to_image_format(qimage.format());
  106. // create input and output images on the gpu
  107. compute::image2d input_image(context, width, height, format);
  108. compute::image2d output_image(context, width, height, format);
  109. // copy host qimage to gpu image
  110. compute::qt_copy_qimage_to_image2d(qimage, input_image, queue);
  111. // apply box filter
  112. box_filter_image(input_image, output_image, 7, 7, queue);
  113. // copy gpu blurred image from to host qimage
  114. compute::qt_copy_image2d_to_qimage(output_image, qimage, queue);
  115. // show image as a pixmap
  116. QLabel label;
  117. label.setPixmap(QPixmap::fromImage(qimage));
  118. label.show();
  119. return app.exec();
  120. }