首页 > 其他分享 >OPENCV入门总结

OPENCV入门总结

时间:2024-09-21 22:48:29浏览次数:11  
标签:总结 入门 merge cv2 OPENCV contours 图像 np 轮廓

        在近期对计算机视觉的学习中,有一些心得与感受和大家一起分享,并且也说一些我做题目用到的函数和一些常见错误

TEST1:图像边框

对矩形的轮廓识别与绘制,难点在于利用色彩来选中红色图形与绿色图形进行处理(后面的几个题也是利用了相同的方法对图像进行特定操作)

我们在对图像进行处理时,总会有一个读取图像-操作图像-显示图像-(保存图像)的流程

基础不变的就是图像读取

import cv2
image = cv2.imread('picture.png')# 读取图像

对于特殊操作,还可以引入一些特殊库

import numpy as np

难点:转换到HSV颜色空间进行操作(注意读取后的图像是非黑即白的二度值,便于操作)

hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)#转换图像为hsv
# 定义红色的HSV范围
lower_red = np.array([0, 120, 70])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)

边缘检测主要是对灰度值进行操作和分析的,所以要将提取的二度值图像转为灰度图

彩色图像灰度处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 

gray = cv2.cvtColor(end, cv2.COLOR_BGR2GRAY)

在使用边缘检测,绘制边缘

# 应用Canny边缘检测
edges = cv2.Canny(gray, 100, 200)
## 查找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 0, 0), 3)

最后是最固定的在指定窗口内显示图像(同时包含窗口创建与显示)

# 显示结果
cv2.imshow('Result1', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

最后两行是为了使图像显示持续。

TEST2:图像特殊处理+边框

WAY1:霍夫圆处理

对非连续图像进行外部轮廓,难点在于对残缺图像的处理,其处于最小图形框内

img_gray = cv2.imread('picture.png', 0)

img_color = cv2.imread('picture.png', -1)  # 原始图像,包含alpha通道,保留图像透明度?

对图像降噪以及霍夫圆函数

# 应用中值滤波
img_blurred = cv2.medianBlur(img_gray, 5)

# 使用霍夫圆变换检测圆
circles = cv2.HoughCircles(img_blurred, cv2.HOUGH_GRADIENT, 2, 100,#dp累加器分辨率与图像分辨率的反比
                           param1=50, param2=30, minRadius=85, maxRadius=200)#圆的精度,以及半径选取
if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        cv2.circle(img_color, (i[0], i[1]), i[2], (0, 0, 0), 2)#园周边轮廓
        cv2.circle(img_color, (i[0], i[1]), 2, (0, 0, 255), 12)  # 中心点的颜色改为红色以便区分

  图像显示(即以一个图形的顶点为圆心画圆)

WAY2开运算闭运算

先使用HSV对指定颜色图形进行区分,使其转化二度值图像

闭运算
kernel = np.ones((3,3 ), np.uint8)#建立核(计算像素基值)
r1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, kernel,iterations=3)
#闭运算,使间隙融合
r1 = cv2.morphologyEx(r1, cv2.MORPH_OPEN, kernel,iterations=1)
#开运算,使合并扩散图像更为规范

可以看出,使用开闭运算得到的图形更为规范,效果也更符合要求。

TEST3角点寻找

这考验的是对函数的运用和HSV颜色区

重点:识别角和绘制角点

# 识别角
corners = cv2.goodFeaturesToTrack(mask2, maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)

# 绘制角点(如果 corners 不为空)
if corners is not None:
    corners = np.int0(corners).reshape((-1, 2))  # 如果需要转换,并且 corners 不是整数,则进行转换并调整形状
    for i in corners:
        x, y = i.ravel()
        cv2.circle(img, (x, y), 6, (0, 0,0), -1)  # 使用黑色绘制角点

效果展示

TEST4:面积计算并显示

对处理区域进行识别

# 转换为 HSV 色彩空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 设置绿色 HSV 阈值
lower_green = np.array([50, 100, 50])
upper_green = np.array([70, 255, 255])

# 创建掩码
mask_green = cv2.inRange(hsv, lower_green, upper_green)#颜色过滤,区域定位

查找轮廓,针对二度值图像

# 查找轮廓
contours, hierarchy = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

重难点:计算面积函数(第一个轮廓是因为只有一个轮廓)

# 假设我们想要处理第一个轮廓
    area = cv2.contourArea(contours[0])
    print(f"第一个轮廓的面积是: {area}")

那么,我们该如何在计算机里用文字体现所需内容呢?绘制文本就是一大学习要点


# 检查是否找到轮廓
if contours:
    # 假设我们想要处理第一个轮廓
    area = cv2.contourArea(contours[0])
    print(f"第一个轮廓的面积是: {area}")

    # 设置文本参数
    text = f"Area: {area}"
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 1
    font_color = (0, 0, 0)  # 黑色
    line_type = 2

    max_contour = max(contours, key=cv2.contourArea)#针对绿色图像

    # 计算轮廓的矩
    M = cv2.moments(max_contour)

    # 计算中心点
    if M["m00"] != 0:
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
    else:
        cX, cY = 0, 0

        # 在原始图像上绘制面积文本
    cv2.putText(img, text, (cX,cY), font, font_scale, font_color, line_type)

请注意,为了满足题目在图形中心显示文本的要求,我们不得不去计算图像的中心点x,y:并文本放置于计算出的(x,y)内

可以看见,Area的A与三角形的顶点在一条直线上,就完成了所需条件。

TEST5多个图像的最小矩形框计算

这是我找函数最难的一题/-\,理解其实很简单,但是计算机思维里面我还没有接触到识别图像直接计算共同外界矩形的函数,后面经过查找发现了一个好玩的——OBB包围盒

先计算出每个图像的最小包围矩形

然后在通过对顶点的值域计算,求出共同的最小包围矩形

图像是我想要的那么一回事了,但是代码的推演运算还是很陌生的,就纠结在如何使红色矩形脱离最小矩形的运算中,简单的HSV筛选似乎不能直接套用。

后面调试,发现其实也是对一个二度值的个图像:最小矩形框计算——矩形框顶点计算——顶点整型化后取最小包围矩形

import numpy as np
import cv2

src = cv2.imread('picture.png')
cv2.imshow('src', src)

split_res = src.copy()  # 显示每个轮廓结构
merge_res = src.copy()  # 显示合并后轮廓结构,复制图像便于操作和体现

# # 将图像从BGR转换到HSV
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
# 定义颜色范围
lower_blue = np.array([100, 120, 70])
upper_blue = np.array([140, 255, 255])
lower_green = np.array([60, 100, 50])
upper_green = np.array([180, 255, 255])

# 创建掩模
mask1 = cv2.inRange(hsv, lower_blue, upper_blue)
mask2 = cv2.inRange(hsv, lower_green, upper_green)
mask = cv2.bitwise_or(mask1, mask2)

contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

merge_list = []#另一个空间
for cnt in contours:
    rect = cv2.minAreaRect(cnt)#计算最小面积矩形

    box = cv2.boxPoints(rect)#获取矩形顶点
    box = np.int0(box)#浮点变整点
    split_res = cv2.drawContours(split_res, [box], 0, (0, 0, 255), 2)#分别绘制矩形
    merge_list.append(cnt)#在list上存储当前轮廓


contours_merge = np.vstack([merge_list[0], merge_list[1]])
for i in range(2, len(merge_list)):#循环合并剩余轮廓
    contours_merge = np.vstack([contours_merge, merge_list[i]])

rect2 = cv2.minAreaRect(contours_merge)#计算合并后轮廓的最小面积矩形
box2 = cv2.boxPoints(rect2)#获取最小面积矩形的顶点
box2 = np.int0(box2)
merge_res = cv2.drawContours(merge_res, [box2], 0, (0, 0, 0), 2)#绘制矩形
cv2.imshow('merge_res', merge_res)
cv2.waitKey(0)
cv2.destroyAllWindows()

当当当当当!要求的效果就体现出来啦!

不过图像的倾斜角还没有体现出来emmm,看大佬演示的时候说只需要一个小函数,不过我没有找到那个小函数是什么哈哈哈哈哈,然后在网上找到的函数又太复杂,好几大行?

angle = rect[2]

# Output the result and angle
plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))
plt.title(f"Angle: {angle:.2f} degrees")

但是在我的代码里面它跑不起来啊啊啊啊,无奈。小小遗憾,不过今天晚上应该能解决掉,

加油加油!

总结

感悟

虽然困难重重,不过看着对题目从恐惧变成了解再到熟悉相应的知识点和函数,真的是很有成就感,而且从零到一的过程也很值得赞叹!成长耶耶耶!

不过距离正真的指标还需要自己走很多路,把C语言完结,还有单片机没开始,其他计算机视觉的知识点也不熟练……有方向总是好的

易错及经验

1.图片和代码放在同一个文件

2.注意对象名的统一性

3.区分函数对二度值和灰度值的要求

4.特殊的函数应用要调取想要的库

5.不要拼写错误,不要编写错误!!!

6.可以利用cv2.imshow()来检验步骤的失误

7.不要羞于询问,学长学姐,同学甚至文心一言,都是你很好的助手,求助也是一种能力!

8.有做事的决心和信心,就能坚持做好事情。

标签:总结,入门,merge,cv2,OPENCV,contours,图像,np,轮廓
From: https://blog.csdn.net/liliumH/article/details/142391216

相关文章

  • Qt表格入门
    摘要    表格作为数据展示的界面,会在很多场景下使用。Qt为我们提供了使用简单方便和扩展性强的表格视图,这里做一个简单的入门整理。    个人能力有限,有错误欢迎留言指正,如果你有更好的方法,也欢迎分享讨论。关键词    Qt、表格、过滤、筛选、自定义单元格、排序......
  • 【JavaWeb从入门到精通系列】 - JavaSE基础篇(1) - 抽象,静态,单例设计模式
    一、抽象1、存在意义似是而非的,像却又不是;具有某种特征,但不完整。Animal仅是一种会吃会睡的对象,再无其他行为,不够具体,不够完整。程序是用来模拟现实世界,解决实际问题的,现实世界中存在的都是动物具体的子类对象,并不存在动物对象,所以,Animal不应该被独立创建成对象。如何......
  • 【JavaWeb从入门到精通系列】 - JavaSE基础篇(1) -面向对象
    一、封装1、存在意义public对属性的设置或者修改没有任何限制隐藏该隐藏的,暴露该暴露的。封装之后设置set和get方法2、封装//1、将需要封装的属性修饰符设置为private(私有的,在外界无法访问)privateintage;//年龄//正常情况下通过创建对象可以访问属性Students......
  • CSP-J 2024 入门组初赛第一轮初赛试题及答案解析
    CSP-J2024入门组初赛第一轮初赛试题及答案解析一、单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项)132位int类型的存储范围是()A-2147483647~+2147483647B-2147483647~+2147483648C-2147483648~+2147483647D-2147483648~+2147483648答案C......
  • java分页方案总结
    1LimitOffset分页2Limit指定主键Id过滤3HasMore滚动查询4ElasticSearch分页查询 ”使用mysqllimit分页就行了,分页查询用得着四种写法吗?" 这可能是很多人的想法。的确mysqllimitoffset是可以胜任分页的,但是另外三种办法在其他场景表现更好。大家最熟悉的就是如下......
  • 9月20日总结
    今天进行了Java补测,题目比较简单,得了满分代码如下packagecom.exam;//*班级:信2305-1//学号:20234102//姓名:孙艺伟*/importjava.util.Scanner;classStudent{privateStringstunumber;//存储学生的学号(有8位数字组成)privateStringname;//存储......
  • 适合新手入门的靶场 TryHackMe
    对于不少喜欢网络安全的小伙伴,一直在很焦虑。如何学习网络安全,但由于各类平台和自身硬件等方面的限制。学习起来很吃力,故而本文为搭建分享一款在线靶场环境TryHackMe推荐理由对自身硬件没有太高的要求,有个浏览器就行了。支持THMAttackBox无需安装kali等系统,在浏览器直......
  • AI绘画实操 Stable Diffusion 到底怎么玩儿,新手必看的AI绘画入门安装使用教程
    大家好,我是灵魂画师向阳2024年,是AI绘画技术飞速发展的一年,各种AI绘画工具层出不穷,为了让大家在了解和学习AI绘画的过程中少走弯路,今天我将详细介绍目前世界上使用用户最多,社区最大,生态最丰富的免费图像生成模型——StableDiffusion,并为你提供详细的安装教程,让你轻松踏入AI......
  • 一文通Maven :入门配置详解与最佳实践、进阶技巧、项目案例分析、常用依赖
    Maven是我们开发中的基础工具之一,尤为重要。它不仅仅是构建工具,还是项目管理、依赖管理、插件管理的强大平台。本文将通过对Maven配置进行详尽分析,并结合实际项目案例,讨论如何有效配置和优化Maven,提升项目的管理和开发效率。一、Maven基础概念与配置结构Maven的核心......
  • go语言基础入门(一)
    变量声明:批量声明变量:变量赋值:声明变量同时为变量赋值可以在变量声明时为其赋值go中赋值时的编译器会自动根据等号右侧的数据类型自动推导变量的类型使用:=进行赋值匿名变量常量常量计数器iota1.使用场景2.基本用法3.简化语法4.自定义增量5.复杂使用go的类似枚......