颜色识别算法

pull/15/head
eazzy 5 months ago
parent 75e6794501
commit cc3bef23a2

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.10)
project(RGB)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(RGB RGB.cpp)
target_link_libraries(RGB ${OpenCV_LIBS})

@ -0,0 +1,80 @@
import cv2
import numpy as np
def detect_and_draw_color(frame):
# 将BGR图像转换为HSV格式
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 定义红色和黄色的HSV范围
# 这里的范围可能需要根据实际情况进行调整
red_lower = np.array([170, 150, 90])
red_upper = np.array([180, 230, 200])
yellow_lower = np.array([40,80, 90])
yellow_upper = np.array([110, 170, 220])
# 创建红色和黄色的掩码
red_mask = cv2.inRange(hsv, red_lower, red_upper)
yellow_mask = cv2.inRange(hsv, yellow_lower, yellow_upper)
# 应用形态学操作去除噪声
kernel = np.ones((5, 5), np.uint8)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_OPEN, kernel)
# 找到掩码中的轮廓
red_contours, _ = cv2.findContours(red_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
yellow_contours, _ = cv2.findContours(yellow_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 初始化伤员等级
patient_level = ""
# 绘制红色边框和标注
if red_contours:
# 找到最大的红色轮廓
max_red_contour = max(red_contours, key=cv2.contourArea)
if cv2.contourArea(max_red_contour) > 500: # 设置一个面积阈值
x, y, w, h = cv2.boundingRect(max_red_contour)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.putText(frame, 'Urgent', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
patient_level = "严重"
# 绘制黄色边框和标注
if yellow_contours:
# 找到最大的黄色轮廓
max_yellow_contour = max(yellow_contours, key=cv2.contourArea)
if cv2.contourArea(max_yellow_contour) > 500: # 设置一个面积阈值
x, y, w, h = cv2.boundingRect(max_yellow_contour)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)
cv2.putText(frame, 'Medium', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 255), 2)
patient_level = "中等"
# 如果检测到颜色,打印伤员等级
if patient_level:
print(f"根据颜色识别确定伤员等级为:{patient_level}!")
return frame
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
# 读取一帧视频
ret, frame = cap.read()
if not ret:
print("无法捕获视频流,请检查摄像头是否正确连接。")
break
# 检测颜色并绘制边框和标注
result_frame = detect_and_draw_color(frame)
# 显示结果
cv2.imshow('Color Detection', result_frame)
# 按 'q' 退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头和销毁所有窗口
cap.release()
cv2.destroyAllWindows()

@ -0,0 +1,37 @@
import cv2
import numpy as np
def mouse_callback(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
pixel = frame[y, x]
hue, sat, val = cv2.split(cv2.cvtColor(np.uint8([[pixel]]), cv2.COLOR_BGR2HSV))
print(f'H: {hue[0, 0]}, S: {sat[0, 0]}, V: {val[0, 0]}')
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
# 读取一帧视频
ret, frame = cap.read()
if not ret:
print("无法捕获视频流,请检查摄像头是否正确连接。")
break
# 将BGR图像转换为HSV格式
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 设置鼠标回调函数
cv2.namedWindow('HSV Image')
cv2.setMouseCallback('HSV Image', mouse_callback)
# 显示HSV图像
cv2.imshow('HSV Image', hsv)
# 按 'q' 退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头和销毁所有窗口
cap.release()
cv2.destroyAllWindows()

@ -0,0 +1,41 @@
import cv2
import numpy as np
def detect_color(image):
# 将BGR图像转换为HSV格式
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 定义红色和黄色的HSV范围
# 这里的范围可能需要根据实际情况进行调整
red_lower = np.array([0, 50, 50])
red_upper = np.array([10, 255, 255])
yellow_lower = np.array([20, 100, 100])
yellow_upper = np.array([30, 255, 255])
# 创建红色和黄色的掩码
red_mask = cv2.inRange(hsv, red_lower, red_upper)
yellow_mask = cv2.inRange(hsv, yellow_lower, yellow_upper)
# 计算掩码区域内的像素数量
red_pixels = np.sum(red_mask)
yellow_pixels = np.sum(yellow_mask)
# 根据像素数量判断等级
if red_pixels > yellow_pixels:
return "严重"
elif yellow_pixels > red_pixels:
return "中等"
else:
return "健康"
# 读取图像
image = cv2.imread('9cde8539c524cab6c62f22ed188074e.jpg')
# 检测颜色并输出等级
level = detect_color(image)
print(level)
# 显示图像(可选)
cv2.imshow('Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

@ -0,0 +1,148 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.16
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canonical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
# The shell in which to execute make rules.
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake
# The command to remove a file.
RM = /usr/bin/cmake -E remove -f
# Escaping for special characters.
EQUALS = =
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /mnt/d/PROJECT/Detect
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /mnt/d/PROJECT/Detect
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/usr/bin/cmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
/usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /mnt/d/PROJECT/Detect/CMakeFiles /mnt/d/PROJECT/Detect/CMakeFiles/progress.marks
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /mnt/d/PROJECT/Detect/CMakeFiles 0
.PHONY : all
# The main clean target
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast
# clear depends
depend:
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend
#=============================================================================
# Target rules for targets named detect1
# Build rule for target.
detect1: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 detect1
.PHONY : detect1
# fast build rule for target.
detect1/fast:
$(MAKE) -f CMakeFiles/detect1.dir/build.make CMakeFiles/detect1.dir/build
.PHONY : detect1/fast
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
@echo "... all (the default if no target is provided)"
@echo "... clean"
@echo "... depend"
@echo "... rebuild_cache"
@echo "... edit_cache"
@echo "... detect1"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

Binary file not shown.

@ -0,0 +1,239 @@
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#define LINEAR_X 0
#define SIZE 3
#define PI 3.1415926
#define HMaxValue 255
#define SMaxValue 255
#define VMaxValue 255
#define oo 1e9+7
using namespace std;
using namespace cv;
int H_min=100, H_max=124, S_min=43, S_max=255, V_min=46, V_max=255;
Mat img_in;
void Gaussian(Mat input, Mat output, double sigma){
double weight;//权重
double sum = 0;
double Gaussian_Temp[SIZE][SIZE] = {0};//模板
weight = (2*PI*sigma*sigma);
for(int i =0;i <SIZE;i++)
{
for(int j = 0;j < SIZE;j++)
{
int x = i - SIZE/2;
int y = j - SIZE/2;
Gaussian_Temp[i][j] =exp(-(x*x+y*y)/(2.0*sigma*sigma))/weight;
sum += Gaussian_Temp[i][j];
}
}
for(int i = 0; i < SIZE;i++)
{
for(int j = 0;j < SIZE;j++)
{
Gaussian_Temp[i][j] = Gaussian_Temp[i][j]/sum;//归一化处理
//printf("%f ",Gaussian_Temp[i][j]);
}
//printf("\n");
}
int rows = output.rows;
int cols = output.cols;
int channels = input.channels();
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
int sum3[3]={0};
int sum1 = 0;
for(int k=0;k<SIZE;k++)
for(int t=0;t<SIZE;t++)
{
int x=i+k-SIZE/2;
int y=j+t-SIZE/2;
if(x<0||y<0||x>=rows||y>=cols)continue;
double m=Gaussian_Temp[k][t];
if(channels == 1)sum1+=m*input.at<uchar>(x,y);
else if(channels == 3)
{
Vec3b rgb = input.at<Vec3b>(x,y);
sum3[0]+=m*rgb[0];
sum3[1]+=m*rgb[1];
sum3[2]+=m*rgb[2];
}
}
if(channels == 3){
for(int k=0;k<3;k++){
if(sum3[k]>255)sum3[k]=255;
if(sum3[k]<0)sum3[k]=0;
output.at<Vec3b>(i,j)[k]=sum3[k];
}
}
else {
if(sum1>255)sum1=255;
if(sum1<0)sum1=0;
output.at<uchar>(i,j)=sum1;
}
}
}
}
void RBG2HSV(Mat input,Mat output){
int rows=input.rows;
int cols=input.cols;
//cout<<rows<<" "<<cols<<endl;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
Vec3b pix=input.at<Vec3b>(i,j);//012:BGR
float b=1.0*pix[0]/255;
float g=1.0*pix[1]/255;
float r=1.0*pix[2]/255;
float maxrgb=max(r,max(g,b));
float minrgb=min(r,min(g,b));
float diff=maxrgb-minrgb;
float v=maxrgb;
float s=(diff/v);
float h;
if(maxrgb-minrgb<1e-5)h=0;
else if(maxrgb==r)h=60*(g-b)/diff;
else if(maxrgb==g)h=60*(b-r)/diff+120;
else if(maxrgb==b)h=60*(r-g)/diff+240;
if(h<0)h+=360;
else if(h>359)h-=360;
output.at<Vec3b>(i,j)[0]=(int)(h*180/360);
output.at<Vec3b>(i,j)[1]=(int)(s*255);
output.at<Vec3b>(i,j)[2]=(int)(v*255);
}
}
}
/*
*/
void Statistical(Mat input){
int weigth=210,height=300;
Mat output=Mat::zeros(height,weigth,CV_8UC3);
int rows=input.rows;
int cols=input.cols;
int colorNum[7]={0};
int sum=rows*cols;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
Vec3b pix=input.at<Vec3b>(i,j);//012:HSV
if(pix[1]<43||pix[2]<46)continue;
//pix[0]=pix[0]*180/255;
int color=0;
if((pix[0]>=0&&pix[0]<=10)||(pix[0]>=156&&pix[0]<=180))color=0;
else if(pix[0]>=11&&pix[0]<=25)color=1;
else if(pix[0]>=26&&pix[0]<=34)color=2;
else if(pix[0]>=35&&pix[0]<=77)color=3;
else if(pix[0]>=78&&pix[0]<=99)color=4;
else if(pix[0]>=100&&pix[0]<=124)color=5;
else if(pix[0]>=125&&pix[0]<=155)color=6;
colorNum[color]++;
}
}
Scalar Color[7]={Scalar(0,0,255),Scalar(0,125,255),Scalar(0,255,255),Scalar(0,255,0),Scalar(255,255,0),Scalar(255,0,0),Scalar(255,0,255)};
for(int i=0;i<7;i++){
int h=colorNum[i]*height/sum;
rectangle(output,Point(i*30,height),Point((i+1)*30-1, height-h),Color[i],-1);
}
imshow("color",output);
}
void colorDetection(Mat input){
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( input, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) );
if(contours.size()==0)return;
int area=0,x=0,y=0,a=0,b=0,c=0,d=0;
for(int k=0;k<contours.size();k++){
RotatedRect rectPoint = minAreaRect(contours[k]);
Point2f point[4];
//将rectPoint变量中存储的坐标值放到 point的数组中
rectPoint.points(point);
//寻找轮廓的左上角和右下角,算出长宽
int max_x=0,max_y=0,min_x=oo,min_y=oo;
for (int i = 0; i < 4; i++)
{
if (max_x < point[i].x)max_x=int(point[i].x+0.5);
if (max_y < point[i].y)max_y=int(point[i].y+0.5);
if (min_x > point[i].x)min_x=(int)point[i].x;
if (min_y > point[i].y)min_y=(int)point[i].y;
}
if(min_x<0)min_x=0;
if(min_y<0)min_y=0;
if(max_x>=input.cols)max_x=input.cols-1;
if(max_y>=input.rows)max_y=input.rows-1;
if((max_x-min_x)*(max_y-min_y)>area){
area=(max_x-min_x)*(max_y-min_y);
x=min_x;
y=min_y;
a=max_x;
b=max_y;
c=max_x-min_x;
d=max_y-min_y;
}
}
if(c==0||d==0)return;
//截取ROI区域
Mat output=img_in(Rect(x,y,c,d));
imshow("ROI",output);
Mat hsv=Mat::zeros(output.size(),CV_8UC3);
RBG2HSV(output,hsv);
//统计截取之后的图像各种颜色的含量
Statistical(hsv);
}
/*
*/
void thresholdSeq(int var,void* usrdata){
Mat input = *(static_cast<Mat*> (usrdata));
Mat output=Mat::zeros(input.size(),CV_8UC1);
int rows=input.rows;
int cols=input.cols;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
Vec3b pix=input.at<Vec3b>(i,j);//012:HSV
if(pix[0]<H_min||pix[0]>H_max)continue;
if(pix[1]<S_min||pix[1]>S_max)continue;
if(pix[2]<V_min||pix[2]>V_max)continue;
output.at<uchar>(i,j)=255;
}
}
imshow("thresholdSeq",output);
//目标颜色检测
colorDetection(output);
}
int main(int argc, char **argv)
{
//读取原始图像
img_in=imread(argv[1],IMREAD_UNCHANGED);
//检查是否读取图像
if(img_in.empty()){
cout<<"Error! Input image cannot be read...\n";
return -1;
}
imshow("src",img_in);
Mat frOut1=Mat::zeros(img_in.size(),CV_8UC3);
Mat frOut2=Mat::zeros(img_in.size(),CV_8UC1);
// 空域滤波函数
Gaussian(img_in,frOut1,1);
// 色度空间转换
RBG2HSV(frOut1,frOut1);
//阈值分割
namedWindow("thresholdSeq");
createTrackbar("H_min", "thresholdSeq", &H_min, HMaxValue, thresholdSeq,&frOut1);
createTrackbar("H_max", "thresholdSeq", &H_max, HMaxValue, thresholdSeq,&frOut1);
createTrackbar("S_min", "thresholdSeq", &S_min, SMaxValue, thresholdSeq,&frOut1);
createTrackbar("S_max", "thresholdSeq", &S_max, SMaxValue, thresholdSeq,&frOut1);
createTrackbar("V_min", "thresholdSeq", &V_min, VMaxValue, thresholdSeq,&frOut1);
createTrackbar("V_max", "thresholdSeq", &V_max, VMaxValue, thresholdSeq,&frOut1);
waitKey();
return 0;
}
Loading…
Cancel
Save