MATLAB 图像处理(画框、加文字后保存)

imwrite、saves、printf保存图片方法及区别:

https://blog.youkuaiyun.com/qq1987924/article/details/45496133

https://blog.youkuaiyun.com/holybin/article/details/39502077

画框:

使用imwrite保存可以保证图片大小不变,但是使用plot画框,因为没有改变图像原始像素值,因此imwrite后不能将框保存下来。

这是画框的方法是:改变图像的像素值:img(xmin:xmax, ymin:ymin+2, 1)= rand_color(1);  %1为RGB之一,需要1,2,3都赋值,这里只画了一条横线,粗度为2像素

加文字:

close all

clc

I=imread('cameraman.tif');

ti=vision.TextInserter('Test', 'Location', [30 30],'FontSize', 12,'color', rand_color(1,:));  %颜色为rand随机生成的 rand_color = rand(1500,3); 

img=step(ti,I);

figure

subplot(121),imshow(I),title('原始图像')

subplot(122),imshow(J),title('处理后图像,此图像可imwrite')

imwrite(img,[save_path,'\',img_list(t).name]); 

% 清空命令窗口、工作区和关闭所有图形窗口 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 相融合 要确保后面代码的基本功能实现
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值