围绕一系列轮廓绘制边界盒

发布于 2025-02-14 02:02:07 字数 1593 浏览 3 评论 0原文

我试图在一系列轮廓上放置一个界限,如以下内容。顶部轮廓和底部轮廓 image1 我写了以下基本代码,这是结果 image2

import cv2
import numpy as np

img = cv2.imread('light2.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (0, 0, 46), (179, 255, 255))

kernel = np.ones((5,5),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

try: hierarchy = hierarchy[0]
except: hierarchy = []

height, width, _ = img.shape
min_x, min_y = width, height
max_x = max_y = 0

for contour, hier in zip(contours, hierarchy):
  (x, y, w, h) = cv2.boundingRect(contour)
  min_x, max_x = min(x, min_x), max(x+w, max_x)
  min_y, max_y = min(y, min_y), max(y+h, max_y)
  if w > 80 and h > 80:
      cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

if max_x - min_x > 0 and max_y - min_y > 0:
    cv2.rectangle(img, (min_x, min_y), (max_x, max_y), (255, 0, 0), 2)

我很挣扎着逻辑当环境中还有其他轮廓时,例如 image3 。并且仍然只想在顶部和底部轮廓检测周围放一个边界盒(类似 image4 )。但是使用当前代码,它将像这样的边界框放置 image5 。任何帮助都将受到赞赏。

I am trying to put a bounding box around a sequence of contours like the following. A top contour and a bottom contour
image1
I wrote the following basic code and this was the result image2

import cv2
import numpy as np

img = cv2.imread('light2.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (0, 0, 46), (179, 255, 255))

kernel = np.ones((5,5),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

try: hierarchy = hierarchy[0]
except: hierarchy = []

height, width, _ = img.shape
min_x, min_y = width, height
max_x = max_y = 0

for contour, hier in zip(contours, hierarchy):
  (x, y, w, h) = cv2.boundingRect(contour)
  min_x, max_x = min(x, min_x), max(x+w, max_x)
  min_y, max_y = min(y, min_y), max(y+h, max_y)
  if w > 80 and h > 80:
      cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

if max_x - min_x > 0 and max_y - min_y > 0:
    cv2.rectangle(img, (min_x, min_y), (max_x, max_y), (255, 0, 0), 2)

I am kind of struggling with the logic when there are other contours in the environment like in image3. And still want to put a bounding box around the top and bottom contour detection only (something like this image4). But with the current code, it puts the bounding box like this image5. Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小…红帽 2025-02-21 02:02:07

您需要使用拥有的工具来解释计算机所需的内容。我建议使用阈值 - > ConnectedComponents - > 过滤错误的Bbox - > 查找具有相同x位置和≈区域(未实现)的2个bbox - > Union Bboxes

“

代码示例:

import cv2
import numpy as np


def drawStats(img: np.array, arr: np.array):
    for i in range(arr.shape[0]):
        w = arr[i, cv2.CC_STAT_WIDTH]
        h = arr[i, cv2.CC_STAT_HEIGHT]
        l = arr[i, cv2.CC_STAT_LEFT]
        t = arr[i, cv2.CC_STAT_TOP]
        cv2.rectangle(img, (l, t), (l+w,t+h), (20, 0, 255), 3)

def filterStats(arr: np.array) -> np.array:
    result = []
    for i in range(arr.shape[0]):
        w = arr[i, cv2.CC_STAT_WIDTH]
        h = arr[i, cv2.CC_STAT_HEIGHT]
        if w > h * 4:
            result.append(arr[i])
        
    result = np.array(result)
    return result

img = cv2.imread("/Users/alex/Downloads/exo7R.jpg", cv2.IMREAD_GRAYSCALE)
_, img2 = cv2.threshold(img, 230, 255, cv2.THRESH_BINARY)

comp = cv2.connectedComponentsWithStats(img2, connectivity=8)
debugImg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
stats = filterStats(comp[2])
drawStats(debugImg, stats)

cv2.imshow("threshold", img2)
cv2.imshow("found components", debugImg)
cv2.waitKey()

You need to explain computer what you want using tools that you have. I suggest use threshold -> connectedComponents -> filter wrong bboxes -> find 2 bbox with same X position and ≈ area (not implemented) -> union bboxes

result.jpg

Code example:

import cv2
import numpy as np


def drawStats(img: np.array, arr: np.array):
    for i in range(arr.shape[0]):
        w = arr[i, cv2.CC_STAT_WIDTH]
        h = arr[i, cv2.CC_STAT_HEIGHT]
        l = arr[i, cv2.CC_STAT_LEFT]
        t = arr[i, cv2.CC_STAT_TOP]
        cv2.rectangle(img, (l, t), (l+w,t+h), (20, 0, 255), 3)

def filterStats(arr: np.array) -> np.array:
    result = []
    for i in range(arr.shape[0]):
        w = arr[i, cv2.CC_STAT_WIDTH]
        h = arr[i, cv2.CC_STAT_HEIGHT]
        if w > h * 4:
            result.append(arr[i])
        
    result = np.array(result)
    return result

img = cv2.imread("/Users/alex/Downloads/exo7R.jpg", cv2.IMREAD_GRAYSCALE)
_, img2 = cv2.threshold(img, 230, 255, cv2.THRESH_BINARY)

comp = cv2.connectedComponentsWithStats(img2, connectivity=8)
debugImg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
stats = filterStats(comp[2])
drawStats(debugImg, stats)

cv2.imshow("threshold", img2)
cv2.imshow("found components", debugImg)
cv2.waitKey()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文