% 清空命令窗口、工作区和关闭所有图形窗口
clc; clear all; close all;
% 读取图像
a = imread('绿灯1.jpg');
figure('Name','原始图像', 'NumberTitle','off');
imshow(a);
title('检测图像');
% 图像预处理
% 灰度化
gray_image = rgb2gray(a);
% 灰度图像显示
figure('Name','灰度图像', 'NumberTitle','off');
imshow(gray_image);
title('灰度化后的图像');
% 降噪:使用中值滤波
denoised_image = medfilt2(gray_image, [3 3]);
% 平滑:使用高斯滤波
smoothed_image = imgaussfilt(denoised_image, 2);
% 将预处理后的灰度图像转换回RGB图像,以便后续处理
preprocessed_image = cat(3, smoothed_image, smoothed_image, smoothed_image);
% 转换为HSV空间
hsv = rgb2hsv(a);
h = hsv(:,:,1);
s = hsv(:,:,2);
v = hsv(:,:,3);
figure('Name','HSV分解', 'NumberTitle','off');
imshow(hsv);
title('HSV图像');
% 定义颜色阈值范围(HSV空间)
% 优化红色阈值范围,减少误检
red_low = [0, 0.6, 0.4];
red_high = [0.08, 1.0, 1.0];
red_low_2 = [0.9, 0.6, 0.4];
red_high_2 = [1.0, 1.0, 1.0];
% 优化黄色阈值范围
yellow_low = [0.12, 0.6, 0.4];
yellow_high = [0.16, 0.8, 0.9];
% 优化绿色阈值范围
green_low = [0.25, 0.6, 0.4];
green_high = [0.35, 0.8, 0.9];
% 生成颜色掩膜
red_mask = ((h > red_low(1) & h < red_high(1)) | (h > red_low_2(1) & h < red_high_2(1))) & ...
(s > red_low(2) & s < red_high(2)) & ...
(v > red_low(3) & v < red_high(3));
yellow_mask = (h > yellow_low(1) & h < yellow_high(1)) & ...
(s > yellow_low(2) & s < yellow_high(2)) & ...
(v > yellow_low(3) & v < yellow_high(3));
green_mask = (h > green_low(1) & h < green_high(1)) & ...
(s > green_low(2) & s < green_high(2)) & ...
(v > green_low(3) & v < green_high(3));
% 合并掩膜并分析
color_mask = red_mask | yellow_mask | green_mask;
se = strel('disk',3);
clean_mask = imopen(color_mask, se); % 开运算去除小的噪声点
clean_mask = bwfill(clean_mask, 'holes'); % 填充内部孔洞
% 连通区域分析
[L, num] = bwlabel(clean_mask, 8);
STATS = regionprops(L, 'Area', 'Centroid', 'BoundingBox', 'PixelIdxList');
% 显示结果
figure('Name','检测结果', 'NumberTitle','off');
imshow(a);
hold on;
for i = 1:num
if STATS(i).Area < 300 || STATS(i).Area > 8000
continue;
end
bbox = STATS(i).BoundingBox;
pixel_idx = STATS(i).PixelIdxList;
red_pixel_count = sum(red_mask(pixel_idx));
yellow_pixel_count = sum(yellow_mask(pixel_idx));
green_pixel_count = sum(green_mask(pixel_idx));
total_pixels = length(pixel_idx);
red_ratio = red_pixel_count / total_pixels;
yellow_ratio = yellow_pixel_count / total_pixels;
green_ratio = green_pixel_count / total_pixels;
ratio_threshold = 0.2;
if red_ratio > ratio_threshold && yellow_ratio > ratio_threshold
color = '红黄异常';
edge_color = [1 0.5 0];
elseif red_ratio > ratio_threshold
color = '红灯 禁止通行';
edge_color = [1 0 0];
elseif yellow_ratio > ratio_threshold
color = '黄色 尽快通行';
edge_color = [1 1 0];
elseif green_ratio > ratio_threshold
color = '绿色 可以通行';
edge_color = [0 1 0];
else
color = '未知';
edge_color = [0.5 0.5 0.5];
end
rectangle('Position', bbox, 'EdgeColor', edge_color, 'LineWidth', 3);
text(bbox(1)+bbox(3)/2-20, bbox(2)+bbox(4)/2, color, ...
'Color','white', 'FontSize',12, 'HorizontalAlignment','center');
end
hold off; 将这个代码 与function trafficLightRecognitionGUI
clc; clear all; close all;
%% 创建主GUI窗口
fig = figure('Name', '交通信号灯识别系统', 'NumberTitle', 'off',...
'Position', [200 200 1000 600], 'MenuBar', 'none',...
'KeyPressFcn', @(src,event) exitOnEsc(src,event));
%% 创建界面组件
uicontrol('Style', 'pushbutton', 'String', '加载图像',...
'Position', [20 550 100 30], 'Callback', @loadImage);
uicontrol('Style', 'pushbutton', 'String', '预处理图像',...
'Position', [140 550 100 30], 'Callback', @preprocessImage);
uicontrol('Style', 'pushbutton', 'String', '检测信号灯',...
'Position', [260 550 100 30], 'Callback', @detectLights);
uicontrol('Style', 'pushbutton', 'String', '识别状态',...
'Position', [380 550 100 30], 'Callback', @recognizeState);
% 图像显示区域
axOriginal = axes('Parent', fig, 'Position', [0.05 0.4 0.25 0.3]);
axGray = axes('Parent', fig, 'Position', [0.35 0.4 0.25 0.3]);
axBinary = axes('Parent', fig, 'Position', [0.05 0.1 0.25 0.3]);
axRegion = axes('Parent', fig, 'Position', [0.35 0.1 0.25 0.3]);
axResult = axes('Parent', fig, 'Position', [0.65 0.1 0.3 0.6]);
%% 数据存储结构
handles = struct(...
'image', [], 'grayImg', [], 'preprocessed', [],...
'binaryImg', [], 'processedMask', [], 'lights', [],...
'axOriginal', axOriginal, 'axGray', axGray,...
'axBinary', axBinary, 'axRegion', axRegion,...
'axResult', axResult);
guidata(fig, handles);
%% 回调函数定义
function loadImage(~, ~)
[filename, pathname] = uigetfile({'*.jpg;*.png;*.bmp', 'Image Files'});
if isequal(filename, 0), return; end
img = imread(fullfile(pathname, filename));
handles = guidata(gcf);
handles.image = img;
guidata(gcf, handles);
% 显示原始图像
imshow(img, 'Parent', handles.axOriginal);
title(handles.axOriginal, '原始图像');
end
function preprocessImage(~, ~)
handles = guidata(gcf);
if isempty(handles.image), errordlg('请先加载图像'); return; end
% 图像预处理流程
grayImg = rgb2gray(handles.image);
denoised = medfilt2(grayImg, [3 3]);
smoothed = imgaussfilt(denoised, 2);
preprocessed = cat(3, smoothed, smoothed, smoothed);
handles.grayImg = grayImg;
handles.preprocessed = preprocessed;
guidata(gcf, handles);
% 显示预处理结果
imshow(grayImg, 'Parent', handles.axGray);
title(handles.axGray, '灰度化图像');
imshow(handles.preprocessed, 'Parent', handles.axOriginal);
title(handles.axOriginal, '预处理图像');
end
function detectLights(~, ~)
handles = guidata(gcf);
if isempty(handles.preprocessed), errordlg('请先预处理图像'); return; end
% 颜色空间转换
hsv = rgb2hsv(handles.preprocessed);
[h, s, v] = imsplit(hsv);
% 多通道阈值分割(优化阈值范围)
redMask = ((h > 0.9 | h < 0.1) & s > 0.3 & v > 0.2) | ...
((h > 0.08 & h < 0.1) & s > 0.5 & v > 0.3);
yellowMask = (h > 0.1 & h < 0.2) & s > 0.3 & v > 0.4;
greenMask = (h > 0.2 & h < 0.4) & s > 0.3 & v > 0.3;
combinedMask = redMask | yellowMask | greenMask;
% 形态学处理(优化步骤)
se1 = strel('disk', 2);
se2 = strel('square', 2);
cleanMask = imopen(combinedMask, se1);
cleanMask = imclose(cleanMask, se2);
cleanMask = bwareaopen(cleanMask, 300);
handles.processedMask = cleanMask;
guidata(gcf, handles);
% 显示处理结果
imshow(cleanMask, 'Parent', handles.axBinary);
title(handles.axBinary, '二值化结果');
% 区域分析
cc = bwconncomp(cleanMask);
stats = regionprops(cc, 'Area', 'BoundingBox', 'Centroid', 'Eccentricity');
% 增加形状过滤条件
valid = [stats.Area] > 200 & [stats.Area] < 8000 & [stats.Eccentricity] < 0.8;
handles.lights = struct('bbox', {stats(valid).BoundingBox}, ...
'centroid', {stats(valid).Centroid});
% 显示区域定位
imshow(handles.preprocessed, 'Parent', handles.axRegion);
hold on;
for i = 1:numel(handles.lights)
rectangle('Position', handles.lights(i).bbox, ...
'EdgeColor', 'r', 'LineWidth', 2);
end
hold off;
title(handles.axRegion, '信号灯区域定位');
end
function recognizeState(~, ~)
handles = guidata(gcf);
if isempty(handles.lights), errordlg('请先检测信号灯'); return; end
resultImg = handles.preprocessed;
statusStr = {'检测结果:', ''};
for i = 1:numel(handles.lights)
% 颜色识别(优化阈值)
lightImg = imcrop(handles.preprocessed, handles.lights(i).bbox);
hsvLight = rgb2hsv(lightImg);
[h, s, v] = imsplit(hsvLight);
redRatio = mean(h > 0.9 | h < 0.1);
yellowRatio = mean(h > 0.1 & h < 0.2);
greenRatio = mean(h > 0.2 & h < 0.4);
color = '未知';
if redRatio > 0.2
color = '红色';
elseif yellowRatio > 0.2
color = '黄色';
elseif greenRatio > 0.2
color = '绿色';
end
% 亮度检测
brightness = mean(lightImg(:));
if brightness > 100
state = '亮';
else
state = '暗';
end
% 状态判断
status = sprintf('%s-%s', color, state);
statusStr{end+1} = status;
% 绘制结果
centroid = handles.lights(i).centroid;
text(centroid(1), centroid(2), status, ...
'Color', 'white', 'FontSize', 12, ...
'HorizontalAlignment', 'center', ...
'Background', 'k', 'EdgeColor', 'none');
end
% 显示最终结果
imshow(resultImg, 'Parent', handles.axResult);
title(handles.axResult, strjoin(statusStr, '\n'));
end
function exitOnEsc(~, event)
if strcmp(event.Key, 'escape')
close(gcf);
end
end
end 相融合 要确保后面代码的基本功能实现