I am trying to determine if an image contains a specific shape of a hourglass. The shape is always in the fixed location and has a fixed size. However, the background is different and it affects the color of the shape. See examples 1 , 2 and 3: example 1, example 2, example 3

如果沙漏为空,则图像仅包含背景.检测这种形状的最好方法是什么,最大限度地减少假阳性和假阴性?

thresholding(静态和自适应)似乎不太可靠,因为下面的代码对第二个示例不是很好:

缺少某些部件的图像:

image with some parts missing

import cv2

img = cv2.imread('hourglass.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 70, 255, cv2.THRESH_BINARY)[1]
cv2.imshow("thresh", thresh)
cv2.waitKey(0)

我想过手动判断沙漏所在位置的像素 colored颜色 是否接近,但它看起来很"粗糙",可能会给出错误的结果,这取决于阈值的 Select

推荐答案

我为你的图片中构成沙漏的有趣像素制作了一个(相当粗糙的)蒙版,如下所示-mask.png:

enter image description here

然后,我将您的图像转换为HSV色空间,并分离出Saturation通道.通常,在图像饱和且生动的情况下,该值较高;在图像较不生动、较不饱和且较灰色的情况下,该值较低.然后,我计算了遮罩区域中图像的平均值和标准差,然后在遮罩区域之外的区域中再次计算.

我假设沙漏的平均值会很低,因为沙漏是不饱和的,而沙漏的方差也会很低,因为沙漏内部的变化很小.设置结果阈值以匹配您的数据.

#!/usr/bin/env python3

import cv2 as cv

# Load mask with interesting pixels masked as white
mask = cv.imread('mask.png', cv.IMREAD_GRAYSCALE)

def processOne(filename, mask):
    # Load image, convert to HSV, and split out S component
    im = cv.imread(filename)
    HSV = cv.cvtColor(im, cv.COLOR_BGR2HSV)
    _, S, _ = cv.split(HSV)
    # Calculate masked mean and stddev of S component
    mean, stddev =  cv.meanStdDev(S,mask=mask)
    print(f'File: {filename}, MASKED AREA {mean=}, {stddev=}')
    mean, stddev =  cv.meanStdDev(S,mask=~mask)
    print(f'File: {filename}, UNMASKED AREA {mean=}, {stddev=}')

processOne('h1.png', mask)
processOne('h2.png', mask)
processOne('h3.png', mask)

Output:

File: h1.png, MASKED AREA mean=array([[13.89722222]]), stddev=array([[10.40768909]])
File: h1.png, UNMASKED AREA mean=array([[74.00181488]]), stddev=array([[33.2070991]])
File: h2.png, MASKED AREA mean=array([[55.66944444]]), stddev=array([[22.63463815]])
File: h2.png, UNMASKED AREA mean=array([[144.43647913]]), stddev=array([[18.2676475]])
File: h3.png, MASKED AREA mean=array([[15.55833333]]), stddev=array([[12.96799211]])
File: h3.png, UNMASKED AREA mean=array([[96.01270417]]), stddev=array([[32.66029606]])

Python相关问答推荐

从单个列创建多个列并按pandas分组

在编写要Excel的数据透视框架时修复标题行

基本链合同的地址是如何计算的?

不允许AMBIMA API请求方法

在for循环中仅执行一次此操作

有什么方法可以避免使用许多if陈述

从包含数字和单词的文件中读取和获取数据集

将numpy数组存储在原始二进制文件中

根据条件将新值添加到下面的行或下面新创建的行中

try 在树叶 map 上应用覆盖磁贴

处理(潜在)不断增长的任务队列的并行/并行方法

如何使用LangChain和AzureOpenAI在Python中解决AttribeHelp和BadPressMessage错误?

Polars:用氨纶的其他部分替换氨纶的部分

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

在pandas中使用group_by,但有条件

创建可序列化数据模型的最佳方法

将pandas导出到CSV数据,但在此之前,将日期按最小到最大排序

通过ManyToMany字段与Through在Django Admin中过滤

将scipy. sparse矩阵直接保存为常规txt文件

如何将一组组合框重置回无 Select tkinter?