BxOpencvModule.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup OpenCV OpenCV integration
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. use CV\Scalar;
  12. use function CV\{imread, imwrite, rectangle, medianBlur, addWeighted};
  13. class BxOpencvModule extends BxDolModule
  14. {
  15. function __construct(&$aModule)
  16. {
  17. parent::__construct($aModule);
  18. }
  19. public function serviceGetStorages()
  20. {
  21. $aStorageObjects = BxDolStorageQuery::getStorageObjects();
  22. $a = [];
  23. foreach ($aStorageObjects as $r)
  24. $a[$r['object']] = $r['object'];
  25. return $a;
  26. }
  27. public function serviceProcessImage($sFilePath, $sExt = 'jpg')
  28. {
  29. $sImgSmilePath = BX_DIRECTORY_PATH_MODULES . 'boonex/opencv/template/images/Emojis-01.png';
  30. $bBlur = 'blur' == getParam('bx_opencv_option_obfuscation_method');
  31. $src = imread($sFilePath);
  32. $src2 = null;
  33. $netDet = CV\FaceDetectorYN::create(BX_DIRECTORY_PATH_MODULES . 'boonex/opencv/models/opencv_zoo/face_detection_yunet_2022mar.onnx', '', $src->size());
  34. // detect faces
  35. if ($r = $netDet->detect($src)) {
  36. // prepare some data
  37. if ($bBlur) {
  38. $dst = $src->clone();
  39. medianBlur($src, $dst, $this->_blurFactor($src->cols));
  40. }
  41. else {
  42. $src2 = BxDolImageResize::getInstance()->getManager()->make($sFilePath);
  43. }
  44. }
  45. // obfuscate
  46. $fConfidence = (float)getParam('bx_opencv_option_confidence');
  47. $faces = [];
  48. $bDetection = false;
  49. for ($i = 0; $i < $r->rows; $i++) {
  50. $confidence = $r->atIdx([$i,14]);
  51. if ($confidence > $fConfidence) {
  52. $startX = $r->atIdx([$i,0]);
  53. $startY = $r->atIdx([$i,1]);
  54. $w = $r->atIdx([$i,2]);
  55. $h = $r->atIdx([$i,3]);
  56. if ($bBlur) {
  57. $this->_blur($src, $dst, (int)$startX, (int)$startY, (int)$w, (int)$h);
  58. }
  59. else {
  60. $img = BxDolImageResize::getInstance()->getManager()->make($sImgSmilePath);
  61. $x = (int)(1.3 * max($w, $h));
  62. $dx = (int)(($x - max($w, $h)) / 2.0);
  63. $img->resize($x, $x);
  64. $src2->insert($img, 'top-left', (int)$startX - $dx, (int)$startY - $dx);
  65. }
  66. $bDetection = true;
  67. }
  68. }
  69. // save resulted image
  70. if ($bDetection) {
  71. if ($bBlur) {
  72. $sExtReal = pathinfo($sFilePath, PATHINFO_EXTENSION);
  73. if ($sExtReal) {
  74. imwrite($sFilePath, $src);
  75. }
  76. else {
  77. imwrite($sFilePath . '.' . $sExt, $src);
  78. if (file_exists($sFilePath . '.' . $sExt) && unlink($sFilePath))
  79. rename($sFilePath . '.' . $sExt, $sFilePath);
  80. }
  81. }
  82. else {
  83. $src2->save($sFilePath);
  84. }
  85. }
  86. }
  87. private function _blur(&$src, $dst, $x, $y, $w, $h)
  88. {
  89. $iChannels = $src->channels();
  90. for ($j = 1; $j < $src->rows - 1; ++$j) {
  91. for ($i = 1; $i < $src->cols - 1; ++$i) {
  92. for ($ch = 0; $ch < $iChannels; $ch++) {
  93. if ($i >= $x && $i <= $x + $w && $j >= $y && $j <= $y + $h) {
  94. $val = $dst->at($j, $i, $ch);
  95. $src->at($j, $i, $ch, $val);
  96. }
  97. }
  98. }
  99. }
  100. }
  101. private function _blurFactor($inputValue) {
  102. // Ensure the input is within a reasonable range
  103. $inputValue = max(1, $inputValue);
  104. // Scale the logarithmic value to cover the desired output range
  105. $scaledValue = log($inputValue/1000) / log(5000);
  106. // Map the scaled value to the desired output range
  107. $outputRange = 50 - 19;
  108. $scaledOutput = round($scaledValue * $outputRange);
  109. // Adjust the output to be odd
  110. $outputValue = 19 + ($scaledOutput % 2 === 0 ? 1 : 0) + $scaledOutput;
  111. return 1 + 2*$outputValue;
  112. }
  113. }
  114. /** @} */