(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: