[R,C,D] = size(im1); im2 = cat(3,imresize(im2(:,:,1),[R,C]),... imresize(im2(:,:,2),[R,C]),... imresize(im2(:,:,3),[R,C])); function [coorList,num] = SpotTheDifferences(im1,im2) % 平滑 H = fspecial('gaussian',7,3); smooth1 = imfilter(im1,H,'same'); smooth2 = imfilter(im2,H,'same'); % 差 ecolor = uint8(abs(double(smooth1)-double(smooth2))); egray = rgb2gray(ecolor); % 二值 bw = imbinarize(egray); % 去小噪 se = strel('disk',5); obj1 = imopen(bw,se); % 合大体 se = strel('disk',11); obj2 = imclose(obj1,se); % 目标 [label,num] = bwlabel(obj2); coorList = zeros(num,4); for n = 1:num [y,x] = find(label==n); y1 = min(y); y2 = max(y); x1 = min(x); x2 = max(x); coorList(n,:) = [x1,x2,y1,y2]; %% {找不同} [coorList,num] = SpotTheDifferences(im1,im2); %% {绘制} subplot(121),imshow(im1) hold on for n = 1:num drawbox(coorList(n,:)) end subplot(122),imshow(im2) hold on for n = 1:num drawbox(coorList(n,:)) end % ----function---- function drawbox(coor) x1 = coor(1); x2 = coor(2); y1 = coor(3); y2 = coor(4); x = [x1,x1,x2,x2,x1]; y = [y1,y2,y2,y1,y1]; plot(x,y,'r-','LineWidth',2) end
时间: 2024-01-29 15:02:55 浏览: 77
这段代码的作用是找出两张图片的不同之处,并在两张图片上绘制出这些不同之处的框。具体实现过程是先将两张图片进行平滑处理,然后计算它们的差异,再将差异图像转化为二值图像,去除小噪声,合并大体,最后找出目标区域并绘制框。其中,SpotTheDifferences函数用来找出不同之处的坐标列表和数量,drawbox函数用来绘制矩形框。
相关问题
grayimg = rgb2gray(img); % 图像二值化 thresh = graythresh(grayimg); bwimg = im2bw(grayimg, thresh); % 边缘检测 edgeimg = edge(bwimg, 'canny'); % 提取数字区域 stats = regionprops(edgeimg, 'BoundingBox'); bbox = cat(1, stats.BoundingBox); numimg = imcrop(edgeimg, bbox); % 将数字图像缩放到统一大小 resizeimg = imresize(numimg, [20,20]); % 提取数字图像的特征 features = extractHOGFeatures(resizeimg); % 加载数字模板 load('digit_templates.mat'); % 计算数字模板的特征 for i = 1:10 template_features(i,:) = extractHOGFeatures(digit_templates{i}); end % 计算数字模板与数字图像的特征距离 for i = 1:10 dist(i) = pdist2(features, template_features(i,:)); end % 找到距离最小的数字模板 [~, idx] = min(dist); % 打印识别结果 fprintf('The digit is %d\n', idx-1);这段代码为什么显示imcrop错误
这段代码中的imcrop函数需要两个参数,第一个是图像,第二个是表示感兴趣区域的矩形框的位置和大小。您需要检查regionprops函数提取的stats结构体中是否有BoundingBox字段,该字段是一个四元组[x, y, width, height],表示感兴趣区域的位置和大小。如果stats中没有BoundingBox字段,则imcrop函数将无法正常工作并报错。另外,您还需要确保矩形框的位置和大小都是整数。
obj = VideoReader('7385387fac45ea1333c10147d8031da8.mp4');%输入视频位置 numFrames = obj.NumberOfFrames;% 帧的总数 for k = 1 :1 % 读取前15帧 frame = read(obj,k);%读取第几帧 %输入图像 I= frame; [H,W,G]=size(I) ; subplot(331),imshow(I),title('原图'); %将图像二值化 I1=im2bw(I,0.6); subplot(332),imshow(I1),title('二值化'); %进行开运算闭运算 se=strel('disk',5); I2=imclose(I1,se); I3=imopen(I2,se); subplot(333),imshow(I3),title('开运算闭运算'); %进行canny算子边缘检测 L=bwlabel(I3); L1=edge(L,'canny'); subplot(334),imshow(L1),title('canny算子边缘检测'); %膨胀运算 SE = strel('disk', 4); J = imdilate(I4, SE); subplot(335),imshow(J),title('将图像膨胀处理'); % 将二值图像转化为连通域标记图像 cc = bwconncomp(J); L = labelmatrix(cc); % 计算所有连通域的属性 props = regionprops(cc, 'area', 'BoundingBox'); % 根据面积筛选出面积大于 1000 的连通域 idx = find(area >= 2000 & area <= 3800); % 创建不同形状的平行四边形 ps1 = polyshape([200 236 315 300],[360 160 180 360]); ps2 = polyshape([420 500 400 350],[360 360 190 220]); % 绘制框选形状 figure; imshow(I); hold on; for i = 1:length(idx) % 判断连通域是否在 ps1 中 if ps1.isinterior(props(idx(i)).BoundingBox(1:2)) plot(ps1); end % 判断连通域是否在 ps2 中 if ps2.isinterior(props(idx(i)).BoundingBox(1:2)) plot(ps2); end end hold off; imwrite(I,strcat('D:\课设图片二',num2str(k),'.jpg'),'jpg');% 保存帧 end改进代码,使每一张图片带有制作的多边形
好的,我可以帮你改进这段代码。你需要在每一张图片上绘制制作的多边形。这可以通过以下步骤实现:
1. 在读取每一帧图像之后,找到面积大于1000且小于3800的连通域,就像你之前做的那样。
2. 创建一个空白图像,大小与原始图像相同。
3. 对于每个满足条件的连通域,找到其位置和大小信息,并创建一个对应的 polyshape 对象。
4. 将 polyshape 对象绘制在空白图像上,可以使用 fill 函数或 line 函数。
5. 将绘制的多边形叠加到原始图像上,可以使用 imshow 函数。
6. 保存带有绘制多边形的图像。
以下是修改后的代码:
```
obj = VideoReader('7385387fac45ea1333c10147d8031da8.mp4');
numFrames = obj.NumberOfFrames;
for k = 1:numFrames
% 读取图像
frame = read(obj,k);
I = frame;
% 将图像二值化
I1 = im2bw(I,0.6);
% 进行开运算闭运算
se = strel('disk',5);
I2 = imclose(I1,se);
I3 = imopen(I2,se);
% 进行canny算子边缘检测
L = bwlabel(I3);
L1 = edge(L,'canny');
% 将图像膨胀处理
SE = strel('disk', 4);
I4 = imdilate(I3, SE);
% 计算所有连通域的属性
cc = bwconncomp(I4);
props = regionprops(cc, 'area', 'BoundingBox');
% 创建空白图像
I_with_polygons = zeros(size(I,1),size(I,2));
% 遍历所有连通域
for i = 1:length(props)
area = props(i).Area;
% 如果连通域面积在指定范围内
if area >= 1000 && area <= 3800
% 获取连通域位置和大小信息
bbox = props(i).BoundingBox;
x = bbox(1);
y = bbox(2);
w = bbox(3);
h = bbox(4);
% 创建 polyshape 对象
ps = polyshape([x x+w x+w x],[y y y+h y+h]);
% 在空白图像上绘制多边形
I_with_polygons = I_with_polygons + poly2mask(ps.Vertices(:,1), ps.Vertices(:,2), size(I,1), size(I,2));
end
end
% 将多边形叠加到原始图像上
I_with_polygons = im2uint8(I_with_polygons);
I_with_polygons = cat(3, I_with_polygons, I_with_polygons, I_with_polygons);
I_with_polygons(:,:,2) = I_with_polygons(:,:,2) + uint8(L1)*255;
I_with_polygons(:,:,3) = I_with_polygons(:,:,3) + uint8(L1)*255;
I_with_polygons = imresize(I_with_polygons, [480 NaN]);
% 显示图像
imshow(I_with_polygons);
% 保存帧
imwrite(I_with_polygons, strcat('D:\课设图片二\frame_', num2str(k), '.jpg'));
end
```
这段代码可以在每一张图片上绘制多边形,并将绘制的多边形叠加在原始图像上,最后保存带有多边形的图像。注意,为了让多边形更清晰,我在代码中添加了一些额外的处理步骤,比如将多边形叠加在边缘检测图像上,使用 imresize 函数调整图像大小等。需要根据你的具体需求进行调整。
阅读全文