TShopping

 找回密碼
 註冊
搜索
查看: 1095|回復: 0
打印 上一主題 下一主題

[教學] Python下應用opencv 背景消除或圖片減法

[複製鏈接]
跳轉到指定樓層
1#
發表於 2021-5-10 21:57:19 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
 
Push to Facebook
背景消除或背景減法是這樣一種假設。我們有2個圖片,一個是靜止的,比如場景,沒有需要檢測的東西,另一個照片則包含了要檢測的對象,但他是侵入了背景裡的東西,或對象。我們就是要檢測這個東西,比如商場進入的小偷,老鼠,或者馬路上通過的車輛。

利用背景減法,我們容易找到我們感興趣的東西。先看看下面2張圖片:



右邊圖片是我們的背景,左邊圖片是我們的結果,我們找到感興趣的部分,就是框起來的部分。框起來前就是我們對比的圖片,或者叫變化的圖片。有這個教授坐在椅子上的部分。

本程序除了opencv要安裝好外,還要裝好imutils。imutils的下載和安裝在 Python下應用opencv的簡單功能演示 一文中有介紹。

本文的原始代碼來自 https://www.pyimagesearch.com/2016/11/21/raspbian-opencv-pre-configured-and-pre-installed/ 的一個教學講稿。

代碼開始部分
註釋裡介紹使用方法:

python image_sub.py --bg 背景文件名 --fg 前景文件名

然後輸入必要的包,命令行參數處理,這裡有缺省參數,你可修改default 後的文件路徑和名


  1. # USAGE 使用方法
  2. # python image_sub.py --bg images/bg.jpg --fg images/adrian.jpg

  3. # import the necessary packages  输入必要的包
  4. import numpy as np
  5. import argparse
  6. import imutils
  7. import cv2

  8. # construct the argument parser and parse the arguments
  9. # 命令行参数处理,2个图片都存在imges 目录里,这里提供缺省值
  10. # 这根据你的情况,更改default 后的文件名,当然也可命令行输入
  11. ap = argparse.ArgumentParser()
  12. ap.add_argument("-b", "--bg", default='images/bg.jpg',
  13.         help="path to background image")
  14. ap.add_argument("-f", "--fg", default='images/adrian.jpg',
  15.         help="path to foreground image")
  16. args = vars(ap.parse_args())
複製代碼

導入圖片並灰度化處理
  1. # load the background and foreground images
  2. # 导入背景,前景文件
  3. bg = cv2.imread(args["bg"])
  4. fg = cv2.imread(args["fg"])

  5. # convert the background and foreground images to grayscale
  6. # 灰度化处理
  7. bgGray = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY)
  8. fgGray = cv2.cvtColor(fg, cv2.COLOR_BGR2GRAY)
複製代碼

背景減法
做減法時,轉換為int32,這樣可以有負值。然後取絕對值,再轉成類型uint8, opencv可以識別。



  1. # perform background subtraction by subtracting the foreground from
  2. # the background and then taking the absolute value
  3. # 背景减法
  4. sub = bgGray.astype("int32") - fgGray.astype("int32")
  5. sub = np.absolute(sub).astype("uint8")
  6. cv2.imshow("sub",sub)
複製代碼

二值化處理
用Otsu 門檻法,轉換上面的減法結果為前景和背景,0為背景,255為前景。圖片效果為下面左邊圖。

然後我們erosion,再dilate消除噪聲,處理效果為下面右邊圖:

erosion dilate的詳細介紹可以看:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html



  1. # find contours in the thresholded difference map and then initialize
  2. # 发现边界
  3. # our bounding box regions that contains the *entire* region of motion
  4. cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
  5. cnts = imutils.grab_contours(cnts)

  6. #给边界初始值
  7. (minX, minY) = (np.inf, np.inf)
  8. (maxX, maxY) = (-np.inf, -np.inf)

  9. # loop over the contours
  10. # 循环计算边界
  11. for c in cnts:
  12.         # compute the bounding box of the contour
  13.         (x, y, w, h) = cv2.boundingRect(c)

  14.         # reduce noise by enforcing requirements on the bounding box size
  15.         # 如果边界值,w 或 w 小于20 就认为是噪音
  16.         if w > 20 and h > 20:
  17.                 # update our bookkeeping variables
  18.                 minX = min(minX, x)
  19.                 minY = min(minY, y)
  20.                 maxX = max(maxX, x + w - 1)
  21.                 maxY = max(maxY, y + h - 1)
複製代碼

繪製長方形,並輸出圖形
  1. # draw a rectangle surrounding the region of motion
  2. # 绘制长方形
  3. cv2.rectangle(fg, (minX, minY), (maxX, maxY), (0, 255, 0), 2)

  4. # show the output image
  5. # 输出图形
  6. cv2.imshow("Output", fg)
  7. cv2.imshow("bg", bg)
  8. cv2.waitKey(0)
複製代碼

綜合在一起的代碼:
  1. # USAGE 使用方法
  2. # python image_sub.py --bg images/bg.jpg --fg images/adrian.jpg

  3. # import the necessary packages  输入必要的包
  4. import numpy as np
  5. import argparse
  6. import imutils
  7. import cv2

  8. # construct the argument parser and parse the arguments
  9. # 命令行参数处理,2个图片都存在imges 目录里,这里提供缺省值
  10. # 这根据你的情况,更改default 后的文件名,当然也可命令行输入
  11. ap = argparse.ArgumentParser()
  12. ap.add_argument("-b", "--bg", default='images/bg.jpg', help="path to background image")
  13. ap.add_argument("-f", "--fg", default='images/adrian.jpg', help="path to foreground image")
  14. args = vars(ap.parse_args())

  15. # load the background and foreground images
  16. # 导入背景,前景文件
  17. bg = cv2.imread(args["bg"])
  18. fg = cv2.imread(args["fg"])

  19. # convert the background and foreground images to grayscale
  20. # 灰度化处理
  21. bgGray = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY)
  22. fgGray = cv2.cvtColor(fg, cv2.COLOR_BGR2GRAY)

  23. # perform background subtraction by subtracting the foreground from
  24. # the background and then taking the absolute value
  25. # 背景减法
  26. sub = bgGray.astype("int32") - fgGray.astype("int32")
  27. sub = np.absolute(sub).astype("uint8")
  28. cv2.imshow("sub",sub)

  29. # threshold the image to find regions of the subtracted image with
  30. # larger pixel differences
  31. thresh = cv2.threshold(sub, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
  32. cv2.imshow("thresh",thresh)

  33. # perform a series of erosions and dilations to remove noise
  34. # erode ,dilate 降噪处理
  35. thresh = cv2.erode(thresh, None, iterations=1)
  36. thresh = cv2.dilate(thresh, None, iterations=1)
  37. cv2.imshow("thresh2",thresh)

  38. # find contours in the thresholded difference map and then initialize
  39. # 发现边界
  40. # our bounding box regions that contains the *entire* region of motion
  41. cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  42. cnts = imutils.grab_contours(cnts)

  43. #给边界初始值
  44. (minX, minY) = (np.inf, np.inf)
  45. (maxX, maxY) = (-np.inf, -np.inf)

  46. # loop over the contours
  47. # 循环计算边界
  48. for c in cnts:
  49.         # compute the bounding box of the contour
  50.         (x, y, w, h) = cv2.boundingRect(c)

  51.         # reduce noise by enforcing requirements on the bounding box size
  52.         # 如果边界值,w 或 w 小于20 就认为是噪音
  53.         if w > 20 and h > 20:
  54.                 # update our bookkeeping variables
  55.                 minX = min(minX, x)
  56.                 minY = min(minY, y)
  57.                 maxX = max(maxX, x + w - 1)
  58.                 maxY = max(maxY, y + h - 1)

  59. # draw a rectangle surrounding the region of motion
  60. # 绘制长方形
  61. cv2.rectangle(fg, (minX, minY), (maxX, maxY), (0, 255, 0), 2)

  62. # show the output image
  63. # 输出图形
  64. cv2.imshow("Output", fg)
  65. cv2.imshow("bg", bg)
  66. cv2.waitKey(0)
複製代碼

文章出處

 

臉書網友討論
*滑块验证:
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2024-5-6 05:02 , Processed in 0.053518 second(s), 25 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表