From cc3bef23a2155a0dedfe7e837db86dd6c2eb3c61 Mon Sep 17 00:00:00 2001 From: eazzy <1044745821@qq.com> Date: Fri, 5 Jul 2024 02:47:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=9C=E8=89=B2=E8=AF=86=E5=88=AB=E7=AE=97?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Detect/CMakeLists.txt | 6 + src/Detect/ColorDetect.py | 80 +++++++++++++ src/Detect/HSV.py | 37 ++++++ src/Detect/ImageDetect.py | 41 +++++++ src/Detect/Makefile | 148 +++++++++++++++++++++++ src/Detect/RGB | Bin 0 -> 95080 bytes src/Detect/RGBDetect.cpp | 239 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 551 insertions(+) create mode 100644 src/Detect/CMakeLists.txt create mode 100644 src/Detect/ColorDetect.py create mode 100644 src/Detect/HSV.py create mode 100644 src/Detect/ImageDetect.py create mode 100644 src/Detect/Makefile create mode 100644 src/Detect/RGB create mode 100644 src/Detect/RGBDetect.cpp diff --git a/src/Detect/CMakeLists.txt b/src/Detect/CMakeLists.txt new file mode 100644 index 0000000..1c4bb67 --- /dev/null +++ b/src/Detect/CMakeLists.txt @@ -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}) diff --git a/src/Detect/ColorDetect.py b/src/Detect/ColorDetect.py new file mode 100644 index 0000000..9c4d039 --- /dev/null +++ b/src/Detect/ColorDetect.py @@ -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() diff --git a/src/Detect/HSV.py b/src/Detect/HSV.py new file mode 100644 index 0000000..63f8159 --- /dev/null +++ b/src/Detect/HSV.py @@ -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() diff --git a/src/Detect/ImageDetect.py b/src/Detect/ImageDetect.py new file mode 100644 index 0000000..f55c416 --- /dev/null +++ b/src/Detect/ImageDetect.py @@ -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() diff --git a/src/Detect/Makefile b/src/Detect/Makefile new file mode 100644 index 0000000..f02fa3a --- /dev/null +++ b/src/Detect/Makefile @@ -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 + diff --git a/src/Detect/RGB b/src/Detect/RGB new file mode 100644 index 0000000000000000000000000000000000000000..0ddbcced0fc2d46c7d9068f151d483164724e9a7 GIT binary patch literal 95080 zcmeFa3wV^p^*{b5WFaDuaMO5S6gA#32?+!hT_6h^xfn^nh{zI>KvqMNCL0LUOE9EO z4ADqI@zNG8+El6Hx2V)xgQ7ueZM+myr8X++Mre(Z+SID~ea_68-FIi-ce%9B|LOmE z+($X@e9oCOXU?2CGw;0bW^Z=SnjRYyGr-`_0OL|42G^UjB;aB^`FcX-$7N(1Lk*WP z#&8+~0mb2emt;lI®%G@j+CL8_O;E$j4TmQz%=e z2g2!M_NSuCpJXHbpUM8zsZ**k6xHkHb3L7AaXm$;4f^DM>@PZ+_Hwvh-$PQ5PA?fG zaYa>oSE3&I<#0dBt#i3OyK%_maZr@vggzIR`j$*czp%9Ef>K{ubrG$_wFvk#M$8I+O%5<{Z8EpD4%a*52aBn`AIhI4!0REr;R=7Hh7^;yN}q6`#Q*5 z`R$;MoyXhYl{Vvhr;VML+xTs}jXiHek5wE#Z`1B*Bp0iGrP;Lml1;m}LEfs}kv8qt z*!X8N>`63EHfnm%km<9P@tj^0NSEmE7$eCrK9RV}|LusA)1m3_)e_H=#JF4NIVnQ_ zgWy}qpAGpj@KD=BQb7jm8OZIneJlah?gYdS>2cObd7YjR+3@7g!ls$d0hy2sQ?K*`P!|<@33;hyU&-%}>!40g7 z~sO6_u|<+jDaL z6TRNTnwr$q)U+i9RlY*lQ0XgMmR*?ZPfaZ>DX8@NE1{$+yU?9mfPdT}UFn6D#b`XQ zvY_z#B?Xm7sV;Y-H^=A8nZCl8v%;M_37r=`nc!PqRdUoeQqR1psow0eifaFq%F2RO zZnK9{;i1r=`j#&%EH5f9tO_4i^5wKtIY2^R#@ymUzc<_GR=Qv#JWzC$9ruNsP*GW4 z7->Mp>f*}sDmQwQLE$1=7lSzyftQ*(x7?2rC?dlqRFwP5{8jE8$WF+iYj5__psCau z*5&gBqakf60%2NtnZLZcvPyJAbDH#Hn)ixof6$S+8D5{y)JVu5!eeRDV0Ti@F}JXw6fv4zgt!d#D|NZAYzl^k z{9@HDljjS|D~pxe5fWAYqQdjeBVYoI%gfH0St#fd@$XXcFS#!-`#StvRGPD5Iq00+ z^3p0d$;c~`lUKskf=lvq#1zV+@T0;J&pr4J1|emP7tF@?zc=r)QV>{H!={ z{+!elF{=xf_z)yC!%GXQs=WSH6~$g(+0t?fU`;9wHL848g49VQsKS~8Z$))wv3G^9 z(qCOrN;#{h##>QbSyf(EQ0nuq@~%h;_7RqfKF&PyPG*Q4bhIu)u)#m+?4Kh|ZZa@M z?OcCpRd!?&bk7AgUZ%=&fijFqyLG9t9GQ4TqBfAFa0`qK-`tNoE9 zmpZ}gEiS8GZXRAl@^Tr(#WfWa?aK<`RYFn?@4T{=nD*Ye#Z}eIi-{@n4&t5GpTg_C zg(cT}mlpVFglW)`U}}75R}_#iFxIQFmU*cnuUN|qd}U-*?KI$tB4ft1Y2NYUQj8h1vZqe-rj1J*ml3>94_>8BGN$F{PnnwSO&vF0qWSr# zhlM@W#2Giq%%dFxZ));ywCg;l&eql!K7o1--1td zM)`b0>BQxwpnQz+808BZ#{NBx-`gmm-YRi?=E!CVSLQx zRc|~7dj=Q>x$Hk@JzNuO#P9)(Iv3)iQR^nF4Wr`&NfkbkZm96-)NmKe2Q)n8Gb!Jr z;g`2ayidayF>ZV)`KsOZjK^#E4#pET{C&ogH2fgrP7NP?hiord!%t;AMZ?n>&(!c< zx-rAYrQyzIiRWneV)jqIh8MB^#Ts72c!`ET%6Nr_zs-1!hJVd?t%fJAmv%O2_*sm% zX!u2pZ_@A_#y4yD^S4UpX!t(H zGd28c#$6iz_RZ3MkA}zAN<3e~7qfpBYxwzhN%;~DzlHG%4gZYs8V#SnN$RQ9@Ov0< z(D3byw`ln5jBnEL4;kOA;a}Y#+ilhGM|qvvrr~=TZ`1G=_Rnq&@8fnmG~9K!Y`0Ux z{fu{M_*TXP8or0|9u4ndyidai-y_>KK9*F)^Qnx-YxoQ7pF|B`-6ZQLX?QE+$r|3q z{z=jBbZ$3O!*5{RrQzEc_h@*4@f-~waj U&GI5e6fa4XS_ti7cgF-;kU7WYBYQT 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 }}#W`O?VxrgT^aBC%4&OVu-E%{xBi&`^ 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 literal 0 HcmV?d00001 diff --git a/src/Detect/RGBDetect.cpp b/src/Detect/RGBDetect.cpp new file mode 100644 index 0000000..8490bae --- /dev/null +++ b/src/Detect/RGBDetect.cpp @@ -0,0 +1,239 @@ +#include +#include +#include +#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 =rows||y>=cols)continue; + double m=Gaussian_Temp[k][t]; + if(channels == 1)sum1+=m*input.at(x,y); + else if(channels == 3) + { + Vec3b rgb = input.at(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(i,j)[k]=sum3[k]; + } + } + else { + if(sum1>255)sum1=255; + if(sum1<0)sum1=0; + output.at(i,j)=sum1; + } + } + } +} +void RBG2HSV(Mat input,Mat output){ + int rows=input.rows; + int cols=input.cols; + //cout<(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(i,j)[0]=(int)(h*180/360); + output.at(i,j)[1]=(int)(s*255); + output.at(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(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 > contours; + vector 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 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 (usrdata)); + Mat output=Mat::zeros(input.size(),CV_8UC1); + int rows=input.rows; + int cols=input.cols; + for(int i=0;i(i,j);//012:HSV + if(pix[0]H_max)continue; + if(pix[1]S_max)continue; + if(pix[2]V_max)continue; + output.at(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; +}