【OpenCV技能树】——OpenCV基础

news2025/3/1 11:25:04

前言

😊😊😊欢迎来到本博客😊😊😊

  目前正在进行 OpenCV技能树的学习,OpenCV是学习图像处理理论知识比较好的一个途径,至少比看书本来得实在。本专栏文章主要记录学习OpenCV的过程以及对学习过程的一些反馈记录。感兴趣的同学可以一起学习、一起交流、一起进步。🌟🌟🌟

  下面框架图主要是OpenCV入门技能树总共有27个知识点,其中包括了8个大章的学习内容,如果感兴趣的可以进一步学习博主写的关于OpenCV的专栏【通俗易懂OpenCV(C++版)详细教程】:

在这里插入图片描述

🎁🎁🎁支持:如果觉得博主的文章还不错或者您用得到的话,可以悄悄关注一下博主哈,如果三连收藏支持就更好啦!这就是给予我最大的支持!😙😙😙


文章目录

      • 一、OpenCV基础
        • 1.1 OpenCV 简介
        • 1.2 OpenCV安装(python版)
        • 1.3 图像的基本操作
        • 1.4 IO与GUI

一、OpenCV基础

1.1 OpenCV 简介

  题目:Hello World

以下 Hello World 程序中,能够正确执行下述操作的是?
		·读取目录下lena图片
		·显示lena图像窗口
		·等待用户输入任意按键后关闭窗口
		·销毁所有窗口

   解析:

import cv2
if __name__=='__main__':
	img = cv2.imread("lena.png")
	cv2.imshow("lena",img)//名称在前,变量在后
	cv2.waitKey(0)
	cv2.destroyAllWindows()

1.2 OpenCV安装(python版)

  题目:极简OpenCV环境安装

·OpenCV 的官方教程里提供了各平台的安装教程:
	https://docs.opencv.org/4.x/df/d65/tutorial_table_of_content_introduction.html
·但是最便利的方式是安装 opencv-python ,安装命令如下:
	pip install opencv-python
·在 Python 中打印出使用的 OpenCV 版本,正确的代码是?

   解析:

import cv2
print(cv2.__version__)

1.3 图像的基本操作

  1、题目:图像像素颜色

·认识颜色空间,OpenCV 常用的颜色空间有:RGB颜色空间、HSV颜色空间、Lab颜色空间。
·以下选项中【不正确】打印像素(100,100)处颜色空间分量名字的是?

   解析:

import numpy as np
import cv2 as cv
if name == 'main':
	img = cv.imread('lena.png', cv.IMREAD_COLOR)
	px = img[100, 100]
	print(f'red:{px[0]}, green:{px[0]}, blue:{px[0]}')//这行代码有误

   OpenCV读图片默认通道是排列BGR

  

  2、题目:图片黑客帝国化

·黑客帝国的图片风格偏绿色,任意图片的每个像素(r,g,b)经过公式转换后即可获得一张“黑客帝国风格图片”:
	r = r^(3/2) 
	g = r^(4/5)
	b = r^(3/2)
·我们对lena图片也做黑客帝国风格化处理:
·框架代码如下:
import numpy as np
import cv2
import math

def hacker(img):
    # TODO(You): 请在此添加代码

if __name__ == '__main__':
    img_origin = cv2.imread('lena.png', cv2.IMREAD_COLOR)
    img = cv2.imread('lena.png', cv2.IMREAD_COLOR)
    print(img.size)
    print(img.shape)

    hacker(img)

    print('显示图片,请按任意键退出')
    numpy_horizontal_concat = np.concatenate((img_origin, img), axis=1)
    cv2.imshow('Lena图片黑客帝国化', numpy_horizontal_concat)
    cv2.waitKey()
    cv2.destroyAllWindows()
·以下选项是对函数 def hacker(img) 的实现,请选出实现【有错】的选项:

   解析:

def hacker(img):
height, width, channels = img.shape
for i in range(0, width):
	for j in range(0, height):
		b, g, r = img.item((i, j))
		hack_b = int(math.pow(b/256.0, 3/2) * 256)
		hack_g = int(math.pow(g/256.0, 4/5) * 256)
		hack_r = int(math.pow(r/256.0, 3/2) * 256)
		img.itemset((i, j), (hack_b, hack_g, hack_r))

  另: item和itemset函数区别

  
  3、题目:梅西足球轨迹

使用 OpenCV 可以方便的剪切粘贴图像上的区域。例如下图是梅西在踢足球:
实现代码如下,需要补全TODO部分:
import cv2
import numpy as np

if __name__ == '__main__':
    img = cv2.imread('ball.jpg', cv2.IMREAD_COLOR)
    start = [493, 594]
    end = [112, 213]
    ball = img[start[0]:start[1], end[0]:end[1]]
    x_step = 101
    y_step = 10
    for i in range(-1, 4):
        # TODO(You): 请在此实现代码

    cv2.imshow("ball_continue", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

   解析:

x_offset = x_stepi
y_offset = y_stepi
img[start[0]-y_offset:start[1]-y_offset, end[0]+x_offset:end[1]+x_offset] = ball

   注意:图像中,一般情况下左上角为坐标轴的(0,0)点,X是水平方向(往右为正,往左为负),Y是竖直方向(往下为正,往上为负)。值得注意的是,起点图片是图二左下角第一哥足球,并非图一的原始足球位置

  从图中可以看出足球轨迹,在Y的方向是往上(为负),在X的方向是往右(为正)。

  pythondata[ 1 : 10, 2:30 ]中 :是表示一个序列,逗号前 1:10表示X的范围从1到10, 2:30表示Y的范围是2到30;
  x_step 所在的线是平行于X轴的水平线;
  y_step所在的直线是平行于Y轴的竖直线;

  所以,x_step是Y方向上的增加量;y_step是X方向上的增加量;足球轨迹在Y的方向是往上(为负),即start[0]-y_offset:start[1]-y_offset,在X的方向是往右(为正),即end[0]+x_offset:end[1]+x_offset


1.4 IO与GUI

  
  1、题目:甲壳虫乐队

一只甲壳虫想组个乐队,但是临时找不到队友。
请使用 OpenCV 读取下面的彩色甲壳虫图片 'bug.jpg',帮助他变身灰色甲壳虫,然后完成组队。
显示甲壳虫乐队并写入到 'bug_band.jpg',以下实现正确的是?

   解析:

import numpy as np
import cv2

if name == 'main':
	bug_img = cv2.imread("bug.jpg") #读取图像
	'''将彩色三通道转换为单通道的灰度图,其转换原理为: 
		GRAY = B * 0.114 + G * 0.587 + R * 0.299'''
	bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
	
	'''COLOR_GRAY2BGR 将单通道的灰度图转换为三通道,这是为了后面的图像合并。
		COLOR_GRAY2BGR的原理:R = G = B = GRAY; A = 0; 
		R,G,B相等时,图像会显示为灰值,不相等时颜色会偏向于较大的基色;'''
	bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
	''' concatenate 合并两副图像,要求两幅图像大小一致,通道一致。
		连接方向(轴向),
		axis=0时,垂直连接;
		axis=1时,水平连接;
		axis=None时,扁平输出,即把二维矩阵中的每个元素横向顺序依次放到一个一维矩阵(列表)中'''
	bug_img_concat = np.concatenate( 
		(bug_img, bug_img_gray_by_BGR_space),
    	axis=1
	)

	cv2.imwrite("bug_band.jpg", bug_img_concat)
	cv2.imshow('甲壳虫乐队', bug_img_concat)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

  
  2、题目:早起的鸟儿有虫吃

早起的鸟儿不但有虫吃,还可以照镜子。请你帮助鸟儿们跟镜像合影。
这是跟镜像合影的效果:

在这里插入图片描述

基本的实现代码如下,合影每10帧采样一次:
import numpy as np
import cv2

if __name__ == '__main__':
    cap = cv2.VideoCapture('birds.mp4')

    out = ...
    # TODO(You): 请在此正确创建待保存的目标mp4文件`out`

    i = 0
    while(cap.isOpened()):

        ret, bird_frame = cap.read()
        if bird_frame is None:
            break

        bird_flip_frame = cv2.flip(bird_frame, 0)
        bird_concat_frame = np.concatenate(
            (bird_frame, bird_flip_frame),
            axis=1
        )

        cv2.imshow('bird_concat_frame', bird_concat_frame)
        if i % 10 == 0:
            out.write(bird_concat_frame)
        i += 1
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    out.release()
    cap.release()

    cv2.destroyAllWindows()

   解析:

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
out = cv2.VideoWriter(
'birds_concat.mp4',
cv2.VideoWriter_fourcc('mp4v'),fps,(width2, height))

  
  3、题目:甲壳虫的Base64之旅

如下的一只甲壳虫,我们希望把它编码成 Base64,再从Base64解码出来。代码框架如下:
以下对两个函数实现正确的是?
import numpy as np
import cv2
import base64
 
def img_to_base64(img):
    # TODO(You):
 
def img_from_base64(img_base64):
    # TODO(You):
 
if __name__ == '__main__':
    img = cv2.imread('bug.jpg')
 
    img_base64 = img_to_base64(img)
    img = img_from_base64(img_base64)
 
    cv2.imshow('img_decode', img)
    cv2.waitKey()
    cv2.destroyAllWindows()

   解析:

def img_to_base64(img):
	return base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()

def img_from_base64(img_base64):
	jpg_original = base64.b64decode(img_base64)
	jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
	img = cv2.imdecode(jpg_as_np, flags=1)
	return img

  
  4、题目:矩形涂鸦画板

编写一个矩形涂鸦画板,实现功能:
	·鼠标左键按下拖动绘制矩形,鼠标左键弹起时完成绘制
	·按'c'键清空画板
	·按'ESC'键退出
基本框架代码如下:
import numpy as np
import cv2 as cv
from random import randint


class Painter:
    def __init__(self) -> None:
        self.mouse_is_pressed = False
        self.last_pos = (-1, -1)
        self.width = 300
        self.height = 512
        self.img = np.zeros((self.width, self.height, 3), np.uint8)
        self.window_name = 'painter'
        self.color = None

    def run(self):
        print('画板,拖动鼠标绘制矩形框,按ESC退出,按c键清空画板')
        cv.namedWindow(self.window_name)
        cv.setMouseCallback(
            self.window_name,
            lambda event, x, y, flags, param: self.on_draw(
                event, x, y, flags, param
            )
        )
        while True:
            cv.imshow(self.window_name, self.img)
            k = cv.waitKey(1) & 0xFF
            if k == ord('c'):
                self.clean()
            elif k == 27:
                break

        cv.destroyAllWindows()

    def on_draw(self, event, x, y, flags, param):
        # TODO(You): 请正确实现画板事件响应,完成功能

    def clean(self):
        cv.rectangle(self.img, (0, 0), (self.height, self.width), (0, 0, 0), -1)

    def begin_draw_rectangle(self, pos1, pos2):
        if self.color is None:
            self.color = (randint(0, 256), randint(0, 256), randint(0, 256))
        cv.rectangle(self.img, pos1, pos2, self.color, -1)

    def end_draw_rectangle(self, pos1, pos2):
        self.color = None


if __name__ == '__main__':
    p = Painter()
    p.run()
以下正确实现鼠标事件,完成画板绘制逻辑的代码是?

   解析:

pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
	self.mouse_is_pressed = True
	self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
	if self.mouse_is_pressed == True:
		self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
	self.end_draw_rectangle(self.last_pos, pos)
	self.mouse_is_pressed = False

   注意:使用变量mouse_is_pressed 去控制,鼠标按下为mouse_is_pressed = true;鼠标移动时当mouse_is_pressed==true时才会绘制;当鼠标抬起时,mouse_is_pressed = false 停止绘制。


🚶🚶🚶 今天的文章就到这里啦~
喜欢的话,点赞👍、收藏⭐️、关注💟哦 ~

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

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

相关文章

Apache apisix默认密钥漏洞(CVE-2020-13945)

目录漏洞描述影响版本漏洞复现声明:本文仅供学习参考,其中涉及的一切资源均来源于网络,请勿用于任何非法行为,否则您将自行承担相应后果,本人不承担任何法律及连带责任。漏洞描述 Apache APISIX 是一个动态、实时、高…

LearnOpenGL-模型加载-3.渲染模型

本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject 文章目录模型加载重要代码读取3D模型递归处理结点的网格加载纹理优化程序代码Model类加载模型流程例子1&…

【运筹优化】拉格朗日松弛 次梯度算法求解整数规划问题 + Java调用Cplex实战

文章目录一、拉格朗日松弛二、次梯度算法三、案例实战一、拉格朗日松弛 当遇到一些很难求解的模型,但又不需要去求解它的精确解,只需要给出一个次优解或者解的上下界,这时便可以考虑采用松弛模型的方法加以求解。 对于一个整数规划问题&…

Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow)

项目介绍 TensorFlow2.X 搭建卷积神经网络(CNN),实现交通标志识别。搭建的卷积神经网络是类似VGG的结构(卷积层与池化层反复堆叠,然后经过全连接层,最后用softmax映射为每个类别的概率,概率最大的即为识别…

chromium 50 chromium57 版本编译启用 widevine 功能

本实验中 chrome 版本为 57.0.2987.98 01 chromium57 在 win11 版本中启用 widevine 功能 01.01 启用 enable_widevine 选项生成 widevine 相关动态库 在chromium 57 版本中,编译时秩序设置 enable_widevinetrue 即可生成 widevinecdm.dll 和 widevinecdmadapter…

windows下maven更新/安装

写在前面: 我的maven学习的比较早,后面windows文件管理分类的时候,把学习用的全部在一个文件夹了,而这个又不好移动进去。 正好也更新一下maven的版本了,不过和重新安装好像差不多了。 现在写的windows的以后,在看看要…

若依框架部署从零开始2023版(前后端分离)

前言电脑最近重装了一次系统,目前什么都没有安装,记录一下从零开始部署前后端分离版本的若依框架系统先去官网把若依源码拉下来代码克隆若依目前已经有很多的版本了,因为现在开发比较流行前后端分离,因此这里演示前后端分离版本点…

外卖点餐系统小程序 PHP+UniAPP

一、介绍 本项目是给某大学餐厅开发的外面点餐系统,该项目针对校内的学生,配送由学校的学生负责配送。因此,该项目不同于互联网的外卖点餐系统。 该系统支持属于 Saas 系统,由平台端、商家端、用户端、以及配送端组成。 其中&a…

从功能测试进阶自动化测试,爆肝7天整理出这一份超全学习指南【附网盘资源】

因为我最近在分享自动化测试技术,经常被问到:功能测试想转自动化,请问应该怎么入手?有没有好的资源推荐?那么,接下来我就结合自己的经历聊一聊我是如何在工作中做自动化测试的。(学习路线和网盘…

盒子拖拽效果,原生js实现

原生js实现拖拽效果 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevic…

keychron机械键盘使用感受

最近入手了一个Keychron无线机械键盘&#xff0c;跟mac本搭配起来使用&#xff0c;体验非常好。记录下使用的感受。 包装 包装很结实&#xff0c;拆开快递盒后&#xff0c;快递盒里有充气袋包裹着键盘盒&#xff0c;键盘盒塑料薄膜封装&#xff0c;没有一点的磕碰。 拆封 不仅外…

运动蓝牙耳机什么牌子好,比较好的运动蓝牙耳机推荐

现在市面上的运动蓝牙耳机越来越多&#xff0c;在选择耳机的时候应该如何入手呢&#xff1f;最重要的是需要按照自己的需求来选择&#xff0c;但在耳机的配置上不能忽视的是耳机的防水等级&#xff0c;运动耳机对防水等级的要求更高&#xff0c;这样能够更好地防御汗水浸湿耳机…

【汇编】四、内存访问(一只 Assember 的成长史)

嗨~你好呀&#xff01; 我是一名初二学生&#xff0c;热爱计算机&#xff0c;码龄两年。最近开始学习汇编&#xff0c;希望通过 Blog 的形式记录下自己的学习过程&#xff0c;也和更多人分享。 上篇系列文章链接&#xff1a;【汇编】三、寄存器&#xff08;一只 Assember 的成…

mgre实验

实验思路 1、首先根据拓扑结构合理分配IP地址&#xff0c;并对各个路由器的IP地址和R5环回接口的IP地址进行配置。 2、让私网中的边界路由器对ISP路由器做缺省路由。 3、根据实验要求&#xff0c;对需要配置不同类型认证的路由器进行认证配置&#xff0c;和需要不同封装的协议…

Git的基本使用以及上传到GitHub

GIT的基本使用一、安装并配置GIT二、Git的基本操作三、使用GIT上传至GitHub四、Git分支一、安装并配置GIT 1.安装GIT连接 GIT安装包链接 2.打开GIT 鼠标右键点击Git Bash Here 安装完 Git 之后&#xff0c;第一件事就是设置自己的用户名和邮件地址。因为通过 Git 对项目进行…

Spark-序列化、依赖关系、持久化

序列化 闭包检查 序列化方法和属性 依赖关系 RDD 血缘关系 RDD 窄依赖 RDD 宽依赖 RDD 任务划分 RDD 持久化 RDD Cache 缓存 RDD CheckPoint 检查点 缓存和检查点区别 序列化 闭包检查 从计算的角度, 算子以外的代码都是在 Driver 端执行, 算子里面的代码都是在 E…

Lesson 9.3 集成算法的参数空间与网格优化和使用网格搜索在随机森林上进行调参

文章目录一、集成算法的参数空间与网格优化1. 学习曲线2. 决策树对象 Tree二、使用网格搜索在随机森林上进行调参1. 建立 benchmark2. 创建参数空间3. 实例化用于搜索的评估器、交叉验证评估器与网格搜索评估器4. 训练网格搜索评估器5. 查看结果在开始学习之前&#xff0c;先导…

拆解DKD loss (建议读完论文哈)

论文链接&#xff1a;https://arxiv.org/abs/2203.08679def dkd_loss(logits_student, logits_teacher, target, alpha, beta, temperature):gt_mask _get_gt_mask(logits_student, target) # 获取掩码other_mask _get_other_mask(logits_student, target)pred_student …

自动化测试——数据驱动测试

数据驱动测试 在实际的测试过程中&#xff0c;我们会发现好几组用例都是相同的操作步骤&#xff0c;只是测试数据的不同&#xff0c;而我们往往需要编写多次用例来进行测试&#xff0c;此时我们可以利用数据驱动测试来简化该种操作。 参数化&#xff1a; 输入数据的不同从而产…

一篇文章教你彻底理解ThreadLocal

文章目录ThreadLocal是什么&#xff1f;ThreadLocal如何使用&#xff1f;特别注意ThreadLocal数据存储存取ThreadLocal原理解析Thread.threadLocals原理Thread.inheritableThreadLocals原理ThreadLocal内存泄漏内存泄漏原因对内存泄漏的补救用完就要删除&#xff08;最终解决&a…