基于opencv测量图片中物体的尺寸(matlab实现)

这篇具有很好参考价值的文章主要介绍了基于opencv测量图片中物体的尺寸(matlab实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、引言

问题重述
已知书本上右下角放一枚一元人民币(直径2.5厘米),请利用计算机视觉技术预测图片中目标的实际尺寸。

1.预测图片中书本的长与宽(单位:厘米)。

2.预测书本右上方用铅笔画的圆圈的外圆直径(单位:厘米)。

现有解决方案:

手动或自动地对已知物体进行标注和测量,得到其尺寸信息(例如像素大小)。 对图像进行预处理,包括灰度化、二值化、去除噪声等操作,以便更好地分割和识别图像中的物体。 利用物体检测或图像分割技术找到图像中待测物体的位置。 根据待测物体在图像中的像素大小和已知物体的像素大小之间的比例关系,计算出待测物体的实际尺寸。

2、解决方法

先对图片进行预处理,后进行高斯模糊(通过测试设置合理的阈值,从而得到较好的效果),通过闭运算增加边缘连通性,用来填充物体内的小空洞,连接断开的轮廓线,由于边缘检测出来的轮廓线通常是不完整的,我们就可以通过这种方法来加强边缘,得到完整的边缘。为了获取到我们书本的轮廓,我们要提取最大的轮廓。然后提取通过霍夫变换检测直线,求出书本轮廓的四条直线的角点,也就是书本的四个角(求角点的时候要进行筛选,筛选出符合要求的点)。再通过角点以及透视变换对图片进行矫正,具体思路是先求出投影映射矩阵:根据4个基准坐标,然后反求出源图像坐标:根据映射矩阵内参数,求一个二元一次方程组。得到矫正后的图片后我们同样要进行高斯模糊。之后我们对图片使用圆形 Hough 变换查找圆,找出最符合的两个圆,从而能求出书本的宽高和手画的圆的直径。

3.实验结果

书本边缘(显示角点):
基于opencv测量图片中物体的尺寸(matlab实现)
透视变换后的图片:
基于opencv测量图片中物体的尺寸(matlab实现)
Hough 变换查找圆,并画出来:
基于opencv测量图片中物体的尺寸(matlab实现)
结果输出:
基于opencv测量图片中物体的尺寸(matlab实现)

4、结论

本次实验运用了较多计算机视觉相关知识,本人能通过课堂所学结合个人想法完成本次实验要求,较符合个人预期,能通过矫正图片等创新方法使得结果更加准确。但也存在一些不足,例如对手画圆的检测并不能十分精准,精度还有待提高。

5、参考文献

[1]图像透视变换原理及现:https://blog.csdn.net/cuixing001/article/details/80261189
[2]透视变换的实现以及透视变换矩阵的构造: https://blog.csdn.net/overflow_1/article/details/80330835
[3]opencv实战–物体尺寸量:https://blog.csdn.net/mbtt00/article/details/107918654文章来源地址https://www.toymoban.com/news/detail-496457.html

6、具体代码如下:

% 读入图片并显示
img = imread('image.jpg');
%imshow(img);

% 缩小图片,方便处理
img = imresize(img, 0.5);

% 灰度化
grayImg = rgb2gray(img);

% 高斯模糊
blurImg = imgaussfilt(grayImg, 0.5); % 增加0.5个像素的模糊半径

% Canny边缘检测
edgeImg = edge(blurImg, 'Canny', [0.05, 0.15]); % 设置阈值0.05和0.15
%imshow(edgeImg);
% 闭运算,增加边缘连通性
se = strel('disk', 200); % 200像素大小的圆形结构元素
closedImg = imclose(edgeImg, se);
%imshow(closedImg);
% 提取轮廓
contourImg = bwperim(closedImg, 8); % 连续8个像素才能构成边缘
stats = regionprops(contourImg, 'BoundingBox', 'Area'); % 提取轮廓属性

% 霍夫变换检测直线
[H,T,R] = hough(contourImg);
P = houghpeaks(H, 50);
lines = houghlines(contourImg, T, R, P);

% 直线筛选
maxLength = 0;
longestLines = [];
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
% 计算直线长度
lineLength = norm(xy(1,:) - xy(2,:));
% 判断是否为最长直线
if lineLength > maxLength
longestLines(end+1) = k;
if length(longestLines) > 4
[~, idx] = min(lineLength);
longestLines(idx) = [];
end
maxLength = lineLength;
end
end

% 计算直线交点
corners = zeros(4,2);
idx = 1;
for i = 1:length(longestLines)
for j = i+1:length(longestLines)
xy1 = [lines(longestLines(i)).point1; lines(longestLines(i)).point2];
xy2 = [lines(longestLines(j)).point1; lines(longestLines(j)).point2];
intPoint = lineIntersect(xy1, xy2);
if(intPoint(1)<640)
if(intPoint(2)>0)
corners(idx,:) = intPoint;
idx = idx + 1;
end
end
end
end
imshow(contourImg);title('书本边缘(显示角点)');
hold on;
plot(corners(:,1), corners(:,2), 'ro', 'MarkerSize', 10); % 显示角点
%plot(xy1(:,1),xy1(:,2),'LineWidth',1,'Color','red');
%plot(xy2(:,1),xy2(:,2),'LineWidth',1,'Color','green');
% 找到最大的轮廓,即书本的轮廓
[~, idx] = max([stats.Area]);
bookBox = stats(idx).BoundingBox;




disp(size(corners)) 

% 获取书本轮廓的图像并进行矫正
%bookContour = imcrop(img, bookBox);

% 显示矫正后的图像
%figure;

%imshow(bookContour);




[m,n] = size(grayImg);
dot=corners; %取四个点,依次是左上,右上,左下,右下
dot(:,[1,2])= dot(:,[2,1]); % 变换x y坐标,x=行 y=列
col=round(sqrt((dot(1,1)-dot(2,1))^2+(dot(1,2)-dot(2,2))^2)); %从原四边形获得新矩形宽
row=round(sqrt((dot(1,1)-dot(3,1))^2+(dot(1,2)-dot(3,2))^2)); %从原四边形获得新矩形高
new_img = ones(row,col);
% 原图四个基准点的坐标
x = [dot(1,1),dot(2,1),dot(3,1),dot(4,1)];
y = [dot(1,2),dot(2,2),dot(3,2),dot(4,2)];
% 新图四个基准点坐标
X = [1,1,row,row];
Y = [1,col,1,col];
% 列出投影关系 求出投影矩阵
A=[x(1),y(1),1,0,0,0,-X(1)*x(1),-X(1)*y(1); 
0,0,0,x(1),y(1),1,-Y(1)*x(1),-Y(1)*y(1);
x(2),y(2),1,0,0,0,-X(2)*x(2),-X(2)*y(2);
0,0,0,x(2),y(2),1,-Y(2)*x(2),-Y(2)*y(2);
x(3),y(3),1,0,0,0,-X(3)*x(3),-X(3)*y(3);
0,0 ,0,x(3),y(3),1,-Y(3)*x(3),-Y(3)*y(3);
x(4),y(4),1,0,0,0,-X(4)*x(4),-X(4)*y(4);
0,0,0,x(4),y(4),1,-Y(4)*x(4),-Y(4)*y(4)];%求解变换矩阵的行列式
B = [X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4)]';
C = inv(A)*B;
D = [C(1),C(2),C(3);
C(4),C(5),C(6);
C(7),C(8),1]; % 变换矩阵3*3模式
inv_D = inv(D);
for i = 1:row 
for j = 1:col
% 解二元一次方程组,根据目标图像坐标反求出原图坐标
pix = inv_D * [i j 1]';
pix1 = inv([C(7)*pix(1)-1 C(8)*pix(1);C(7)*pix(2) C(8)*pix(2)-1])*[-pix(1) -pix(2)]';
if pix1(1)<m && pix1(2)<n
new_img(i,j) = img(round(pix1(1)),round(pix1(2))); %最近邻插值
else
new_img(i,j) = 255;
end
end
end 

figure;
new_img=flipud(new_img);%上下翻转
%图像归一化
Bmax=max(max(new_img));
Bmin=min(min(new_img));
new_img=(new_img-Bmin)/(Bmax-Bmin);
imshow(new_img);title('透视变换后')
new_img = imgaussfilt(new_img, 2);
new_img=edge(new_img, 'Canny', [0.05, 0.15]); % 设置阈值0.05和0.15
figure;
imshow(new_img);title('边缘检测')
[centers,radii,metric] = imfindcircles(new_img,[20,500])
centersStrong2 = centers(1:2,:); 
radiiStrong2 = radii(1:2);
metricStrong2 = metric(1:2);
viscircles(centersStrong5, radiiStrong5,'EdgeColor','b');
%长为A,宽为B
[A,B]=size(new_img);
A=(A/radiiStrong2(1,1)*0.5)*2.5;
B=(B/radiiStrong2(1,1)*0.5)*2.5;
%外圆直径
W=(radiiStrong2(2,1)/radiiStrong2(1,1))*2.5;
disp('书本宽为:'+string(B)+'cm'+',书本长为:'+string(A)+'cm');
disp('铅笔所画的圆的外圆直径为:'+string(W)+'cm');



function intPoint = lineIntersect(line1, line2)
% 计算两条直线的交点
% line1: 直线1的两个端点坐标,[x1,y1; x2,y2]
% line2: 直线2的两个端点坐标,[x3,y3; x4,y4]

% 计算直线参数
A1 = line1(1,2) - line1(2,2);
B1 = line1(2,1) - line1(1,1);
C1 = line1(1,1)*line1(2,2) - line1(2,1)*line1(1,2);

A2 = line2(1,2) - line2(2,2);
B2 = line2(2,1) - line2(1,1);
C2 = line2(1,1)*line2(2,2) - line2(2,1)*line2(1,2);

% 计算交点
D = A1*B2 - A2*B1;
if D ~= 0
x = (B1*C2 - B2*C1) / D;
y = (A2*C1 - A1*C2) / D;
intPoint = [x, y];
else
intPoint = [nan, nan];
end
end

到了这里,关于基于opencv测量图片中物体的尺寸(matlab实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【图像处理】基于双目视觉的物体体积测量算法研究(Matlab代码实现)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 本文运用

    2024年02月11日
    浏览(38)
  • OpenCV实现单目相机检测物体尺寸

    目录 步骤: Canny边缘检测算法介绍: 多边形逼近 代码实现: 效果展示: 导入必要的库: cv2 用于图像处理, numpy 用于数组操作。 定义了一个函数 preprocess ,用于对图像进行预处理。首先将图像转换为灰度图,然后进行高斯模糊来平滑图像。接着使用腐蚀操作进一步去除噪

    2024年02月07日
    浏览(43)
  • 基于条纹投影的物体三维形貌测量理论与仿真实验-含Matlab代码

    基于光栅投影的光学三维面形测量具有非接触、精度高、速度快、低成本、全场测量和易于实现等特点,在逆向工程、工业检测、质量控制、虚拟现实、医学诊断、文物修复和物体识别等领域应用广泛。相移轮廓术(PSM)和傅里叶变换轮廓术(FTP)是两种传统方法。相移法计算简单

    2024年02月03日
    浏览(157)
  • 【电赛训练】非接触物体尺寸形态测量 2020年电赛G题

    一、题目要求 具体内容详见非接触物体尺寸形态测量(G 题)——行走的皮卡丘 设计并制作一个非接触式物体形状和尺寸自动测量装置,装置的布置图如图 1所示,测量装置放置在图中所示的测量装置区内,被测目标放置在图中被测目标放置区内,装置能测量被测目标的形状

    2024年02月16日
    浏览(56)
  • python基于OpenCV预测图片中目标的实际尺寸(计算机视觉)

    本次实验需要根据已知的硬币的直径,预测图片中书本的长与宽以及书本右上方用铅笔画的圆圈的外圆直径。可以先对图片进行矫正,找到硬币的轮廓并计算硬币直径占据的像素大小,进而得到实际尺寸和像素的比例系数,然后找到书本和铅笔绘制的圆圈的轮廓,再根据它们

    2024年02月03日
    浏览(56)
  • OpenCV测量图像中物体距离

    先注意 这不是双目摄像头的 测距哦~~ 计算物体之间的距离与计算图像中物体的大小算法思路非常相似——都是从参考对象开始的。我们将使用0.25美分作为我们的参考对象,它的宽度为0.955英寸。 并且我们还将0.25美分总是放在图片最左侧使其容易识别。这样它就满足了我们上

    2024年02月02日
    浏览(40)
  • 【自适应稀疏度量方法和RQAM】疏度测量、RQAM特征、AWSPT和基于AWSPT的稀疏度测量研究(Matlab代码实现)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 这是一份

    2024年02月11日
    浏览(39)
  • Yolov8项目实践——基于yolov8与OpenCV实现目标物体运动热力图

    在数据驱动和定位的世界中,对数据进行解释、可视化和决策的能力变得日益重要。这表明,使用正确的工具和技术可能是项目成功的关键。在计算机视觉领域,存在许多技术来解释从视频(包括录像、流媒体或实时视频)中获取的数据,特别是在评估需要分析交通强度或某

    2024年04月29日
    浏览(41)
  • CASAIM与大疆达成全自动化测量技术合作,CASAIM IS全自动化蓝光测量仪实现无人机叶片全尺寸检测及质量控制

    近期,CASAIM与大疆达成全自动化测量技术合作,CASAIM IS全自动化蓝光测量仪实现无人机叶片全尺寸检测及质量控制。 无人机行业在过去几年里取得了迅猛发展, 大疆是全球领先的无人飞行器控制系统及无人机解决方案的研发商和生产商, 客户遍布全球100多个国家。随着技术

    2024年02月16日
    浏览(47)
  • 船舶法兰盘法兰管件3D扫描尺寸测量|三维扫描检测|CAV测量-CASAIM

    第一章 服务背景 船舶建造多采用分段建造法,即将零件、预装好的部件在胎架上组合焊接成分段或总段,然后由船台装配成整船的建造方法。而当船体合拢组装时,在船体上遍布着各种各样的管道,这些管道都需要互相完全适配以确保船体安装的完整。 第二章 原有服务方案

    2024年02月12日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包