华南农业大学|图像处理与分析技术综合设计|题目解答:读取电表示数

news2025/1/10 3:08:11

l 设计任务:

ipa05.jpg是一幅电气柜上的电表图像,试采用图像处理与分析技术,设计适当的

算法和程序,找出电流表所在的区域,提取其指针位置,计算指针与表盘下沿

的夹角,进而判断当前电表的读数(提示:电流表的读数范围为 0~400A)。请

按统一要求写出算法原理、设计流程,并完成程序测试与分析等内容。

l 算法设计:

解题思路:处理图片使之只剩下三根电流表的指针,通过霍夫变换定位指针所对应的直线,通过直线与过0刻度的直线之间的角度算出此时电表的读数。

设计方案说明

读入图片,转换成灰度图,然后使用阈值分割,去除一部分不重要信息。之后设置去除大连通域函数与去除小连通域函数的阈值,得到三根指针。然后通过腐蚀操作,得到最终可进行霍夫变换的图像。对于经过霍夫变换后得到的三条直线,使用“两端点x坐标和最大”的特点确定第一排左数第二个表对应的直线,使用“两端点y坐标和最大”的特点确定第二排左数第一个表对应的直线,剩余的直线对应第一排左数第二个表,如此确定直线对应的表。将直线化为单位向量,与水平方向的单位向量求夹角,并由“0~400A 对应 0~90度”的原则确定电表读数。

关键算法的设计原理

转换成灰度图:降低信息维数,减少处理难度

阈值分割:表针为黑色,其灰度强度低,将灰度图小于某强度的像素点提取出来,可以去除很多不重要信息。

去除大/小连通域:由于三根指针的面积差不多,则可按面积的规则筛选出只有三根指针作为连通域的图像。

腐蚀操作:使指针变薄,以实现霍夫变换精准识别。

两个单位向量求夹角:高等数学。

算法步骤

读取图像→转化为灰度图→阈值分割→去掉大连通域→去掉小连通域→腐蚀→霍夫变换→识别直线所在表→计算直线单位向量与基准向量求角度→计算电表读数并输出结果

l 程序设计:

算法名称:阈值分割、去除大连通域、开运算、腐蚀、霍夫变换

工具函数

阈值分割:G<110,其中G为原图像经灰度转换得到的灰度图。

去除大连通域:removeLargeArea()函数,为bwareaopen()函数修改而来。作用是去掉像素面积为某个阈值以上的大连通域。

开运算:bwareaopen()。

腐蚀:strel()函数和imerode()函数。

霍夫变换:hough、houghpeaks、houghlines等。

设计分析完成任务。

l 测试分析:

1

图1从左到右,为原图→灰度图→阈值分割后图→去掉大连通域后图→去掉小连通域后图(即开运算)→腐蚀图像后图

其中阈值分割阈值取110。去掉大连通域的阈值取160,去掉小连通域阈值取120。腐蚀使用方形结构元素,宽度为2。

 

图2

图2的霍夫变换检测到了三根指针所对应的直线,符合要求。

图3

图3为电表读数结果,基本符合要求。

代码

removeLargeArea.m

function bw2 = removeLargeArea(varargin)
matlab.images.internal.errorIfgpuArray(varargin{:});
[bw,p,conn] = parse_inputs(varargin{:});

CC = bwconncomp(bw,conn);
area = cellfun(@numel, CC.PixelIdxList);

idxToKeep = CC.PixelIdxList(area <= p);
idxToKeep = vertcat(idxToKeep{:});

bw2 = false(size(bw));
bw2(idxToKeep) = true;

%%%
%%% parse_inputs
%%%
function [bw,p,conn] = parse_inputs(varargin)

narginchk(2,3)

bw = varargin{1};
validateattributes(bw,{'numeric', 'logical'},{'real', 'nonsparse'},mfilename,'BW',1);
if ~islogical(bw)
    bw = bw ~= 0;
end

p = varargin{2};
validateattributes(p,{'double'},{'scalar' 'integer' 'nonnegative'},...
    mfilename,'P',2);

if (nargin >= 3)
    conn = varargin{3};
else
    conn = conndef(ndims(bw),'maximal');
end
iptcheckconn(conn,mfilename,'CONN',3)

主程序

clc,clear

%% 预处理
I = imread('ipa05.jpg'); % 读入图片
G = rgb2gray(I); % 转化灰度
BW1 = G<110; % 阈值提取

%% 保留像素面积(120,160)间的连通域
BW2 = removeLargeArea(BW1,160);
BW3 = bwareaopen(BW2,120);

%% 腐蚀使区域厚度减小
SE = strel('square',2);
BW4 = imerode(BW3,SE);

%% 霍夫变换
[H,theta,rho] = hough(BW4);
peaks = houghpeaks(H,3);
lines = houghlines(BW4,theta,rho,peaks);

%% 用直线的相对位置识别对应的表
% 两端点x坐标和最大,则是第一排第二个表
% 两端点y坐标和最大,则是第二排第一个表
% 剩下的表是第一排第一个表
lines_info = zeros(3,4);
for i = 1:3
    lines_info(i,1) = lines(i).point1(1)+lines(i).point2(1);% x坐标和
    lines_info(i,2) = lines(i).point1(2)+lines(i).point2(2);% y坐标和
    tmp=lines(i).point1 - lines(i).point2;
    lines_info(i,3:4) = tmp/norm(tmp); % 单位向量
end

lines_vector = zeros(3,2);% 储存排序后的向量
a = sortrows(lines_info,'descend');
lines_vector(2,:) = a(1,3:4);
a = sortrows(lines_info,2,'descend');
lines_vector(3,:) = a(1,3:4);
lines_vector(1,:) = lines_info(lines_info(:,3) ~= ...
    lines_vector(2) & lines_info(:,3)~=lines_vector(3),3:4);

%% 使用每条线的单位向量,并与基准单位向量比较,计算夹角
theta = [];
base = [1,0]; % 基准单位向量
for i = 1:3
    theta = [theta acos(abs(dot(base,lines_vector(i,:)))...
        /(norm(base)*norm(lines_vector(i,:))))*180/pi];
end

%% 由计算得到的夹角,输出表的读数
% 0~400A 对应 0~90度,则
disp("第一排左数第一个表读数"+num2str(theta(1)/90*400)+"A");
disp("第一排左数第二个表读数"+num2str(theta(2)/90*400)+"A");
disp("第二排左数第一个表读数"+num2str(theta(3)/90*400)+"A");

%% 测试
figure(1)
subplot(231),imshow(I);title("原图");
subplot(232),imshow(G);title("灰度图");
subplot(233),imshow(BW1);title("阈值分割后图");
subplot(234),imshow(BW2);title("去掉大连通域");
subplot(235),imshow(BW3);title("去掉小连通域");
subplot(236),imshow(BW4);title("腐蚀图像减少区域厚度");

figure(2), imshow(BW4), hold on
max_len = 0;
for k = 1:length(lines)
    xy = [lines(k).point1; lines(k).point2];
    plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

   % Plot beginnings and ends of lines
    plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
    plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

  %  Determine the endpoints of the longest line segment
    len_temp = norm(lines(k).point1 - lines(k).point2);
    if ( len_temp > max_len)
        max_len = len_temp;
        xy_long = xy;
    end
    title("霍夫变换",'FontWeight','bold');
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

车载软件架构——车载诊断软件框架

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 人们会在生活中不断攻击你。他们的主要武器是向你灌输对自己的怀疑&#xff1a;你的价值、你的能力、你的…

vue2+AntdesignVue a-input使用颜色选择器

不需要任何插件即可实现颜色选择器 a-input type设置为color即可 回调函数

vue进阶-消息的订阅与发布

&#x1f4d6;vue基础学习-组件 介绍了嵌套组件间父子组件通过 props 属性进行传参。子组件传递数据给父组件通过 $emit() 返回自定义事件&#xff0c;父组件调用自定义事件接收子组件返回参数。 &#x1f4d6;vue进阶-vue-route 介绍了路由组件传参&#xff0c;两种方式&…

Spring MVC异步上传、跨服务器上传和文件下载

一、异步上传 之前的上传方案&#xff0c;在上传成功后都会跳转页面。而在实际开发中&#xff0c;很多情况下上传后不进行跳转&#xff0c;而是进行页面的局部刷新&#xff0c;比如&#xff1a;上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。 1.1 JSP页面 …

PT:report_timing实用技巧

report_timing -start_end_pair 默认report_timing -to 会报告到endpoint最差一条violation path。 用report_timing -max_path X就会报告到endpoint的X条path&#xff0c;每组startpoint /endpoint只报告最差的一条(在X范围内有多少报多少&#xff0c;下面同理)。 用report…

Android 生成pdf文件

Android 生成pdf文件 1.使用官方的方式 使用官方的方式也就是PdfDocument类的使用 1.1 基本使用 /**** 将tv内容写入到pdf文件*/RequiresApi(api Build.VERSION_CODES.KITKAT)private void newPdf() {// 创建一个PDF文本对象PdfDocument document new PdfDocument();//创建…

什么是从人类反馈中强化学习(RLHF)?

自从OpenAI公司发布ChatGPT以来&#xff0c;人们对大型语言模型(LLM)的这一重大进步感到兴奋。虽然ChatGPT与其他最先进的大型语言模型大小相同&#xff0c;但其性能要高得多&#xff0c;并且承诺支持新的应用程序或颠覆取代原有的应用程序。 ChatGPT的惊人表现背后的主要原因…

NAT—网络地址转换

目录 静态NAT 动态NAT NAPT—easy IP 多对多的NAPT 端口映射—高级用法 NAT—网络地址转换 IPV4地址不够用 NAT ABC—三类地址中截取了一部分地址&#xff08;并且让这部分地址可以重复使用&#xff09;—私网地址 A类地址中&#xff1a;10.0.0.0-10.255.255.255 &#xff08;…

3. 学习分类 - 基于图像大小进行分类

3.1 设置问题 根据图片的尺寸&#xff0c;把图片分为纵向图像和横向图像。这种把图像分成两种类别的问题&#xff0c;就是二分类问题。 纵向图片示例&#xff1a; 横向图片示例&#xff1a; 这样就有了两个训练数据&#xff1a; 增加训练数据&#xff0c;并在图像中表示出来…

mac批量修改文件名为不同名字

mac批量修改文件名为不同名字怎么弄&#xff1f;很多小伙伴通过私信向我求助&#xff0c;用什么方法可以在mac电脑上批量修改文件名称&#xff0c;将大量文件修改成不同的名称。这可能是一项比较麻烦的操作&#xff0c;在电脑上进行过批量重命名的小伙伴都知道&#xff0c;一般…

汉服小姐姐【InsCode Stable Diffusion美图活动一期】

一、 Stable Diffusion 模型在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置&#xff1a; 模型&#xff1a;majicmixRealistic_v6 Lora&#xff1a;hanfu_ming 采样迭代步数&#xff08;steps&#xff09;: 40 采样方法&am…

SCB后备保护器——保护电器的后备力量

在现代社会中&#xff0c;电力设备已经成为了不可或缺的一部分&#xff0c;而在使用电力设备的过程中&#xff0c;由于各种原因&#xff0c;电力设备可能会受到电涌的影响&#xff0c;从而导致设备损坏或者火灾事故的发生。为了有效保护电力设备的安全稳定运行&#xff0c;研发…

数据科学分析全流程步骤

知识图谱以结构化的“知识”来存储与表示海量数据&#xff0c;作为承载底层海量知识并支持上层智能应用的重要载体&#xff0c;它在智能时代中扮演了极其重要的角色。然而&#xff0c;由于知识图谱高度结构化的特点&#xff0c;我们常常需要构建结构化查询语句&#xff08;SPAR…

卷积神经网络(CNN)原理详解

近些年人工智能发展迅速&#xff0c;在图像识别、语音识别、物体识别等各种场景上深度学习取得了巨大的成功&#xff0c;例如AlphaGo击败世界围棋冠军&#xff0c;iPhone X内置了人脸识别解锁功能等等&#xff0c;很多AI产品在世界上引起了很大的轰动。 而其中 卷积神经网络&am…

微服务 云原生:gRPC 客户端、服务端的通信原理

gRPC Hello World protoc 是 Protobuf 的核心工具&#xff0c;用于编写 .proto 文件并生成 protobuf 代码。在这里&#xff0c;以 Go 语言代码为例&#xff0c;进行 gRPC 相关代码编写。 下载 protoc 工具&#xff1a;https://github.com/protocolbuffers/protobuf/releases&a…

饭堂人群密度检测之Pythton

完整资料进入【数字空间】查看——baidu搜索"writebug" 一、饭堂人群密度检测 二、选题背景 在这个人工智能快速发展的时代&#xff0c;智能交通、智能机器人等人工智能化产品不断出现。作为人工智能的重要分支&#xff0c;计算机视觉起到了重要作用。它通过一系列的…

面试题更新之-使用 base64 编码的优缺点

文章目录 base64 编码是什么&#xff1f;使用 base64 编码的优缺点 base64 编码是什么&#xff1f; Base64编码是一种将二进制数据转换为ASCII字符的编码方式。它将三个字节的二进制数据分割成四组&#xff0c;每组6个比特&#xff0c;然后将这些6个比特转换为可打印的ASCII字…

前端学习——Web API (Day5)

BOM操作 Window对象 BOM 定时器-延时函数 案例 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&q…

XSS 攻击的检测和修复方法

XSS 攻击的检测和修复方法 XSS&#xff08;Cross-Site Scripting&#xff09;攻击是一种最为常见和危险的 Web 攻击&#xff0c;即攻击者通过在 Web 页面中注入恶意代码&#xff0c;使得用户在访问该页面时&#xff0c;恶意代码被执行&#xff0c;从而导致用户信息泄露、账户被…

Docker 部署 Jenkins (一)

Docker 部署 Jenkins (一) 一. 安装 jenkins $ mkdir -p /home/tester/data/docker/jenkins $ vim jenkins:lts-jdk11.sh./jenkins:lts-jdk11.sh 内容 #! /bin/bash mkdir -p /home/tester/data/docker/jenkins/jenkins_homesudo chown -R 1000:1000 /home/tester/data/dock…