如何使用OpenCV Python很好地检测颜色

发布于 2025-01-27 07:32:37 字数 2742 浏览 2 评论 0原文

(这不是整个代码,而是主要部分)

这只是我想做的一个简单的项目,而不是学校或其他任何项目。

我想很好地分割红色零件,但是我不能,因为光线和相机质量总是在变化。 我正在图片上的相机上使用它。 (我认为没有必要将其放在这里)

我认为此解决方案不是最适合这个项目的项目:

lower_red = np.array([15, 15, 110], dtype="uint8")
upper_red = np.array([75, 75, 255], dtype="uint8")

因此,我想知道如何使其独立于环境并检测到我必要的内容。

也将其制成其他颜色(黑色,蓝色,绿色,橙色,黄色),

import cv2 as cv
import numpy as np


# just resizing the image if it's too big
def base(img):
    if img.shape[0] > 1000 or img.shape[1] > 1000:
        scale_percent = 20  # percent of original size
        width = int(img.shape[1] * scale_percent / 100)
        height = int(img.shape[0] * scale_percent / 100)
        dim = (width, height)
    else:
        dim = (img.shape[1], img.shape[0])

    img = cv.resize(img, dim, interpolation=cv.INTER_AREA)
    return img


def sort(img):
    lower_red = np.array([15, 15, 110], dtype="uint8")
    upper_red = np.array([75, 75, 255], dtype="uint8")

    # lower_blue = np.array([70, 15, 15], dtype="uint8")
    # upper_blue = np.array([255, 75, 75], dtype="uint8")
    
    mask_red = cv.inRange(img, lower_red, upper_red)
    # mask_blue = cv.inRange(img, lower_blue, upper_blue)

    red_detected_output = cv.bitwise_and(img, img, mask=mask_red)
    # blue_detected_output = cv.bitwise_and(img, img, mask=mask_blue)
    
    cv.imshow("color detection", red_detected_output)

    return red_detected_output


def contour(img, frame):
    _, thresh_gray = cv.threshold(cv.cvtColor(img, cv.COLOR_BGR2GRAY),
                                  1, 255, cv.THRESH_BINARY)

    kernel = np.ones((3, 3), np.uint8)
    morph = cv.morphologyEx(thresh_gray, cv.MORPH_OPEN, kernel)
    kernel = np.ones((5, 5), np.uint8)
    morph = cv.morphologyEx(morph, cv.MORPH_CLOSE, kernel)

    contours, _ = cv.findContours(morph,
                                  cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)

    for c in contours:
        # if the contour is not sufficiently large, ignore it
        if cv.contourArea(c) < 500:
            continue

        M = cv.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])

        # get the min area rect
        rect = cv.minAreaRect(c)
        box = cv.boxPoints(rect)
        # convert all coordinates floating point values to int
        box = np.int0(box)
        cv.putText(frame, "red", (cX - 20, cY - 20), cv.FONT_HERSHEY_COMPLEX, 1.0, (0, 0, 255))
        # draw a red 'nghien' rectangle
        cv.drawContours(frame, [box], 0, (0, 0, 255), 2)
    # cv.imshow('img', frame)

这是输出:

“”

(It is not the whole code, it's just the main part)

It's just a simple project I wanted to do, not school or anything.

I want to segment out the red parts nicely, but I can't because the light and the camera quality is always changing.
I'm using this on camera on the picture. (I don't think it's necessary to put that in here)

I don't think this solution is the best for this kinda project:

lower_red = np.array([15, 15, 110], dtype="uint8")
upper_red = np.array([75, 75, 255], dtype="uint8")

So I want to know how to make it independent of the environment and detect what is necessary for me.

Also make it for the other colors too (black, blue, green, orange, yellow)

import cv2 as cv
import numpy as np


# just resizing the image if it's too big
def base(img):
    if img.shape[0] > 1000 or img.shape[1] > 1000:
        scale_percent = 20  # percent of original size
        width = int(img.shape[1] * scale_percent / 100)
        height = int(img.shape[0] * scale_percent / 100)
        dim = (width, height)
    else:
        dim = (img.shape[1], img.shape[0])

    img = cv.resize(img, dim, interpolation=cv.INTER_AREA)
    return img


def sort(img):
    lower_red = np.array([15, 15, 110], dtype="uint8")
    upper_red = np.array([75, 75, 255], dtype="uint8")

    # lower_blue = np.array([70, 15, 15], dtype="uint8")
    # upper_blue = np.array([255, 75, 75], dtype="uint8")
    
    mask_red = cv.inRange(img, lower_red, upper_red)
    # mask_blue = cv.inRange(img, lower_blue, upper_blue)

    red_detected_output = cv.bitwise_and(img, img, mask=mask_red)
    # blue_detected_output = cv.bitwise_and(img, img, mask=mask_blue)
    
    cv.imshow("color detection", red_detected_output)

    return red_detected_output


def contour(img, frame):
    _, thresh_gray = cv.threshold(cv.cvtColor(img, cv.COLOR_BGR2GRAY),
                                  1, 255, cv.THRESH_BINARY)

    kernel = np.ones((3, 3), np.uint8)
    morph = cv.morphologyEx(thresh_gray, cv.MORPH_OPEN, kernel)
    kernel = np.ones((5, 5), np.uint8)
    morph = cv.morphologyEx(morph, cv.MORPH_CLOSE, kernel)

    contours, _ = cv.findContours(morph,
                                  cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)

    for c in contours:
        # if the contour is not sufficiently large, ignore it
        if cv.contourArea(c) < 500:
            continue

        M = cv.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])

        # get the min area rect
        rect = cv.minAreaRect(c)
        box = cv.boxPoints(rect)
        # convert all coordinates floating point values to int
        box = np.int0(box)
        cv.putText(frame, "red", (cX - 20, cY - 20), cv.FONT_HERSHEY_COMPLEX, 1.0, (0, 0, 255))
        # draw a red 'nghien' rectangle
        cv.drawContours(frame, [box], 0, (0, 0, 255), 2)
    # cv.imshow('img', frame)

Here is the output:

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文