知识点

像素操作之逻辑操作

  • bitwise_and
  • bitwise_xor
  • bitwise_or

上面三个类似,都是针对两张图像的位操作

  • bitwise_not

针对输入图像, 图像取反操作,二值图像分析中经常用
image.png
补充说明:

图像像素值不是只有 0 和 1,当按位与操作时,结果取两者之间的较小值;按位或操作时,结果取两者间的较大值;异或操作时,结果取两者之间的差值,所以示例代码显示结果的重叠区域的差值为 0,所以是黑色~

有读者可能会疑惑,为什么按位与操作时,结果取两者之间的较小值?可以这样理解,把 0-255 转换成二进制后,再按位与操作,结果就是较小的那个值~

C++代码

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. using namespace std;
  4. using namespace cv;
  5. void day07() {
  6. Mat src = imread("E:\\_Image\\OpenCVTest\\girl.jpg");
  7. if (src.empty()) {
  8. cout << "could not load image.." << endl;
  9. return;
  10. }
  11. imshow("input", src);
  12. // 取反操作
  13. Mat dst;
  14. bitwise_not(src, dst);
  15. imshow("dst", dst);
  16. // create image1
  17. Mat src1 = Mat::zeros(Size(400, 400), CV_8UC3);
  18. Rect rect(100, 100, 100, 100);
  19. src1(rect) = Scalar(0, 0, 255);
  20. imshow("input1", src1);
  21. // create image2
  22. Mat src2 = Mat::zeros(Size(400, 400), CV_8UC3);
  23. rect.x = 150;
  24. rect.y = 150;
  25. src2(rect) = Scalar(0, 0, 255);
  26. imshow("input2", src2);
  27. // 逻辑操作
  28. Mat dst1, dst2, dst3;
  29. bitwise_and(src1, src2, dst1);
  30. bitwise_xor(src1, src2, dst2);
  31. bitwise_or(src1, src2, dst3);
  32. // show results
  33. imshow("dst1", dst1);
  34. imshow("dst2", dst2);
  35. imshow("dst3", dst3);
  36. waitKey(0);
  37. }

Python代码

  1. import cv2 as cv
  2. import numpy as np
  3. # 查看版本
  4. print(cv.__version__)
  5. # 创建图像 1
  6. src1 = np.zeros(shape=[400, 400, 3], dtype=np.uint8)
  7. src1[100:200, 100:200, 1] = 255
  8. src1[100:200, 100:200, 2] = 255
  9. cv.imshow("input1", src1)
  10. # 创建图像 2
  11. src2 = np.zeros(shape=[400, 400, 3], dtype=np.uint8)
  12. src2[150:250, 150:250, 2] = 255
  13. cv.imshow("input2", src2)
  14. # 进行逻辑运算
  15. dst1 = cv.bitwise_and(src1, src2)
  16. dst2 = cv.bitwise_xor(src1, src2)
  17. dst3 = cv.bitwise_or(src1, src2)
  18. # 显示结果
  19. cv.imshow("dst1", dst1)
  20. cv.imshow("dst2", dst2)
  21. cv.imshow("dst3", dst3)
  22. # 图像取反操作
  23. src = cv.imread("E:/_Image/OpenCVTest/girl.jpg")
  24. cv.imshow("input", src)
  25. dst = cv.bitwise_not(src)
  26. cv.imshow("dst", dst)
  27. # 等待键盘输入 释放内存
  28. cv.waitKey(0)
  29. cv.destroyAllWindows()

Javascript代码

  1. <template>
  2. <div>
  3. <p>图像像素逻辑操作</p>
  4. <p id="status">OpenCV.js is loading...</p>
  5. <div class="inputoutput">
  6. <img id="imageSrc" src="imgs/girl.jpg" />
  7. </div>
  8. <div class="inputoutput">
  9. <canvas id="canvasOutput"></canvas>
  10. <div class="caption">canvasOutput</div>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. export default {
  16. name: "day07",
  17. mounted() {
  18. this.init();
  19. },
  20. methods: {
  21. init() {
  22. setTimeout(() => {
  23. if (window.cv) {
  24. this.onOpenCvReady(window.cv);
  25. } else {
  26. this.init();
  27. }
  28. }, 500);
  29. },
  30. onOpenCvReady(cv) {
  31. document.getElementById("status").innerHTML = "OpenCV.js is ready.";
  32. let src = cv.imread("imageSrc");
  33. let dst = new cv.Mat();
  34. // 官方文档链接:https://docs.opencv.org/4.5.0/dd/d4d/tutorial_js_image_arithmetics.html
  35. // 图像取反
  36. // cv.cvtColor(src, src, cv.COLOR_RGBA2RGB);
  37. // cv.bitwise_not(src, dst);
  38. // 创建图像 1
  39. let src1 = new cv.Mat(512, 512, cv.CV_8UC3);
  40. for (let i = 100; i < 200; i++) {
  41. for (let j = 100; j < 200; j++) {
  42. src1.ucharPtr(i, j)[0] = 255;
  43. src1.ucharPtr(i, j)[1] = 255;
  44. }
  45. }
  46. // 创建图像 2
  47. let src2 = new cv.Mat(512, 512, cv.CV_8UC3);
  48. for (let i = 150; i < 250; i++) {
  49. for (let j = 150; j < 250; j++) {
  50. src2.ucharPtr(i, j)[0] = 255;
  51. }
  52. }
  53. // 像素逻辑操作
  54. // cv.bitwise_and(src1, src2, dst)
  55. // cv.bitwise_or(src1, src2, dst)
  56. cv.bitwise_xor(src1, src2, dst);
  57. cv.imshow("canvasOutput", dst);
  58. src.delete();
  59. src1.delete();
  60. src2.delete();
  61. dst.delete();
  62. },
  63. },
  64. };
  65. </script>
  66. <style lang="scss" scoped>
  67. </style>

image.png
image.png
image.png