《Practical Python and OpenCV》学习记录 -1

本文介绍了Adrian的《Practical Python and OpenCV》与《case study》两本书的学习笔记,涵盖了图像基础知识、绘图操作、图像处理等核心内容,详细解析了OpenCV库在Python中的应用,适合初学者入门。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     从本科毕业到现在研究生一年级都开学一个月都没有更新博客了,趁着十一的几天时间学习了一下Adrian大佬的《Practical Python and OpenCV》以及《case study》,读下来发现确实是两本入门opencv的好书,并且书也写的通俗易懂。以下用来记录学习的一些知识点和代码。

1.Image Basics

     pixel(像素):可以把图像看成是网格,网格中的每个块就代表了像素。

     coordinate system(图像中的坐标系统):

                                                      

     水平为x轴,竖直的为y轴,并且左上角为坐标原点,这一点需要注意。而图像的形状(shape)表示的顺序是height、width。即image.shape[0 : 2] = [height, width], 与我们的直观有些违背,直观而言是长宽,但是在计算机中先是宽再是长,这是因为方便之后的矩阵运算。还有一个需要注意的是在opencv中,彩色图像的构造顺序是BGR,而不是RGB。

import argparse
import cv2

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
    help = "Path to the image")
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
print("width: {} pixels".format(image.shape[1]))
print("height: {} pixels".format(image.shape[0]))
print("channels: {}".format(image.shape[2]))
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.imwrite("newimage.jpg",image)

  该段简单的代码解释了图片存储的顺序。

import cv2
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True, 
    help="path to the image ")
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
cv2.imshow("Original", image)

(b, g, r) = image[0,0]
print("Pixel at [0,0] - Red:{}, Green:{}, Blue:{}".format(r, g, b))
image[0,0] = (0, 0, 225)
(b, g, r) = image[0, 0]
print("Pixel at [0,0] - Red:{}, Green:{}, Blue:{}".format(r, g, b))
corner = image[0:100, 0:100]
cv2.imshow("Corner", corner)
#注意切片操作对应到坐标轴下的坐标
image[0:100, 0:100] = (0, 255, 0)

cv2.imshow("Updated", image)
cv2.waitKey(0)

 注意切片操作下所对应的坐标,image[0:100, 0:100],第一个是切片是y轴,第二个切片是x轴。

2.Drawing

 该部分用于解释如何利用opencv在图像中绘制一些基础的图形:矩形,直线,圆。

                                    

        画直线的函数:cv2.line(canvas, (300, 0), (0, 300), (0,255,0), 3),第一个参数是需要绘制直线的图像;第二个和第三个参数是直线的起始和终止坐标;第四个参数为直线的颜色;第五个参数为直线的尺寸。

        画矩形的函数:cv2.rectangle(canvas, (50, 200), (200, 225),(0,255,0), 5),第一个参数是需要绘制矩形的图像;第二个和第三个是矩形的左上角和右下角的坐标;第四个参数为矩形颜色;第五个坐标为尺寸。若第五个参数取-1的话,则进行填充。

        画圆的函数:cv2.circle(canvas, (centerX, centerY), r, white, 3),第一个参数同上;第二个tuple参数为圆的圆点坐标;第三个参数为圆的半径;第四个为颜色;第五个为尺寸,若为-1则进行填充。

import cv2
import numpy as np  

canvas = np.zeros((300, 300, 3), dtype="int8")
green = (0, 225, 0)
cv2.line(canvas, (0, 0), (300, 300), green)
cv2.imshow("Canvas",canvas)
cv2.waitKey(0)

red = (0, 0, 255)
cv2.line(canvas, (300, 0), (0, 300), red, 3)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

cv2.rectangle(canvas, (10, 10), (60, 60), green)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

cv2.rectangle(canvas, (50, 200), (200, 225), red , 5)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

blue = (255, 0, 0)
cv2.rectangle(canvas, (200, 50), (255, 125), blue, -1)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

canvas = np.zeros((300, 300, 3), dtype="uint8")
(centerX, centerY) = (canvas.shape[1] // 2, canvas.shape[0] // 2)
white = (255, 255, 255)

for r in range(0, 175, 25):
    cv2.circle(canvas, (centerX, centerY), r, white, -2)

cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

for i in range(0, 25):
    radius = np.random.randint(5, high = 200)
    color = np.random.randint(0, high = 256, size =(3,)).tolist()
    pt = np.random.randint(0, high = 300, size = (2,))
    cv2.circle(canvas, tuple(pt), radius, color, -1)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

3.Image processing 

   这部分包括了translation,rotation, resizing, flipping和clipping一些基本的操作。

   Translation:利用的函数,cv2.warpAffine(image, M, (image.shape[1], image.shape[0])),第一个参数为需要操作的图像;第个参数为平移矩阵,M=([1,0,x], [0,1,y]), x为需要水平移动的像素个数,为正数则右移,负数左移,y为需要竖直移动的像素个数,为正数则下移,负数上移;第三个参数为图像的大小,注意是image.shape[1]在前面,代表的x方向的长度。

def translate(image, x ,y):
    M = np.float32([[1, 0, x], [0, 1, y]])
    shifed = cv2.warpAffine(image, M, (image.shape[1], 
        image.shape[0]))
    
    return shifed

  定义了一个图像平移的函数。

   Rotation:也是利用函数,cv2.warpAffine(image, M, (image.shape[1], image.shape[0])),就其中的参数M有所变化,但M由函数M = cv2.getRotationMatrix2D(center, angle, scale)确定,center为需要旋转中心;angle为需要旋转角,正数代表逆时针旋转,负数代表逆时针旋转;scale为旋转图片的尺寸,即把图片尺寸转化为scale倍,再进行旋转。

def rotate(image, angle, center = None, scale = 1.0):
    (h, w) = image.shape[0:2]

    if center is None:
        center = (w // 2, h // 2)

    M = cv2.getRotationMatrix2D(center, angle, scale)
    rotated = cv2.warpAffine(image, M, (w, h))

    return rotated

  定义了一个图像旋转函数

  Resize:利用函数cv2.resize(image, dim, interpolation = cv2.INTER_AREA),需要注意的是第二个参数,因为resize可以根据height和width分别来的.interpolation参数是插值的方式

# resize the image by the specifying width or height
def resize(image, width = None, height = None, inter = 
    cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[0:2]

    if width is None and height is None:
        return image
    
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))

    resized = cv2.resize(image, dim, interpolation = inter)

    return resized

 其中dim的顺序是(width,height),而image.shape返回的前两个值是(height,width).例如需要在给定width长度下,对height进行resize时.比例r=width/image.shape[2],而dim=(width,int(height.r)).

  Flipping:利用函数cv2.flip(image, 1),第二个参数可以取1,0,-1,其中1代表水平翻转,即关于y轴对称;0代表垂直翻转,即关于x轴对称;-1代表水平和垂直同时翻转.

#0 represent vertically; 1 represent horizontally; -1 represent both
def flip(image, style):
    flipped = cv2.flip(image, style)
    return flipped

  Cropping:直接利用numpy中array的切片性质即可完成,如:

## crop 的时候注意图像在numpy的数组中它的第一维代表Y坐标,第二维代表X坐标
## 所以如下操作的坐标范围是(240, 30) 到(335, 120)
cropped = image[30:120, 240:335]

  Arithmetic:图片的算数操作,在opencv中和numpy中操作是不一样的,当使用的数据都是8位的无符号整形数时(np.uint8).

#the anwer is constraint as 255
print("max of 255:{}".format(cv2.add(np.uint8([200]), 
    np.uint8([100]))))
#the anwer is constraint as 0
print("min of 0: {}".format(cv2.subtract(np.uint8([50]),
    np.uint8([100]))))
#the anwer is modulo arithmetic as 200+100-255-1=44
print("wrap around: {}".format(np.uint8([200]) + np.uint8([100])))
#the anwer is modulo arithmetic as 50+255-100+1=206
print("wrap around: {}".format(np.uint8([50]) - np.uint8([100])))

  Bitwise operations:按位操作,可以对两个图像进行按位操作包括了:AND,OR,XOR,NOT这四种操作.

bitwiseAnd = cv2.bitwise_and(rectangle, circle)
bitwiseOr = cv2.bitwise_or(rectangle, circle)
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
bitwiseNot = cv2.bitwise_not(circle)

 Masking:找出我们在图片中感兴趣的部分.

#constructing a mask to conclude the patch which we are
#interesting,the mask has same size of image
mask = np.zeros(image.shape[:2], dtype = "uint8")
(cX, cY) = (image.shape[1] // 2, image.shape[0] // 2)
#for examle ,wo are interesting the patch of image's center area
cv2.rectangle(mask, (cX - 75, cY -75), (cX + 75, cY + 75)
    , 255, -1)
#using the bitwise_and function and adding the third parameters
masked = cv2.bitwise_and(image, image, mask = mask)

  Split and merge channels:在分离时用的是cv2.split(image)函数,注意分离出来的顺序是BGR,对于融合而言,也需要注意它的BGR顺序.

(B, G, R) = cv2.split(image)
image = cv2.merge([B,G,R])

  Color space: 转换图片的颜色空间,便于后续的操作,用到的函数:.cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), 第二个参数为需要转换的颜色类型.

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)

 

 

以上是一些在Opencv下基本的图像处理操作.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值