御神楽的学习记录之数字图像与机器视觉基础


前言

计算机视觉是一门研究如何使机器“看”的科学,更进一步的说,就是是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更适合人眼观察或传送给仪器检测的图像。作为一个科学学科,计算机视觉研究相关的理论和技术,试图建立能够从图像或者多维数据中获取‘信息’的人工智能系统。这里所 指的信息指Shannon定义的,可以用来帮助做一个“决定”的信息。因为感知可以看作是从感官信号中提 取信息,所以计算机视觉也可以看作是研究如何使人工系统从图像或多维数据中“感知”的科学。


一、简单图片格式

1.位图格式

在这里插入图片描述
上图从左到右依次为BMP位图,原图,单色位图,16色位图,32色位图以及256色位图

在这里插入图片描述
不同色位图的占用空间不同
文件头
表示位图文件大小,类型,和偏离文件头的长度。
在这里插入图片描述
在这里插入图片描述

2.位图大小计算

位图大小计算公式为:
长×高×位深度

在这里插入图片描述
上图图片大小可计算为:(220×220×16)/8/1024=94.531kb

3.图片压缩格式

原图:在这里插入图片描述
经过格式转换

在这里插入图片描述
BMP原图占空间比PNG、JPG和GIF的均大的多
在这里插入图片描述

二、SVD图像特征提取

1.代码

import numpy as np
import os
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib as mpl
from pprint import pprint


def restore1(sigma, u, v, K):  # 奇异值、左特征向量、右特征向量
    m = len(u)
    n = len(v[0])
    a = np.zeros((m, n))
    for k in range(K):
        uk = u[:, k].reshape(m, 1)
        vk = v[k].reshape(1, n)
        a += sigma[k] * np.dot(uk, vk)
    a[a < 0] = 0
    a[a > 255] = 255
    # a = a.clip(0, 255)
    return np.rint(a).astype('uint8')


def restore2(sigma, u, v, K):  # 奇异值、左特征向量、右特征向量
    m = len(u)
    n = len(v[0])
    a = np.zeros((m, n))
    for k in range(K+1):
        for i in range(m):
            a[i] += sigma[k] * u[i][k] * v[k]
    a[a < 0] = 0
    a[a > 255] = 255
    return np.rint(a).astype('uint8')


if __name__ == "__main__":
    A = Image.open("./image.jpg", 'r')
    print(A)
    output_path = r'./SVD_Output'
    if not os.path.exists(output_path):
        os.mkdir(output_path)
    a = np.array(A)
    print(a.shape)
    K = 50
    u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
    u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
    u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
    plt.figure(figsize=(11, 9), facecolor='w')
    mpl.rcParams['font.sans-serif'] = ['simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    for k in range(1, K+1):
        print(k)
        R = restore1(sigma_r, u_r, v_r, k)
        G = restore1(sigma_g, u_g, v_g, k)
        B = restore1(sigma_b, u_b, v_b, k)
        I = np.stack((R, G, B), axis=2)
        Image.fromarray(I).save('%s\\svd_%d.png' % (output_path, k))
        if k <= 12:
            plt.subplot(3, 4, k)
            plt.imshow(I)
            plt.axis('off')
            plt.title('奇异值个数:%d' % k)
    plt.suptitle('SVD与图像分解', fontsize=20)
    plt.tight_layout(0.3, rect=(0, 0, 1, 0.92))
    # plt.subplots_adjust(top=0.9)
    plt.show()

2.运行结果

在这里插入图片描述

三、硬币识别

1.识别原理

在这里插入图片描述
1)先将硬币转为灰度图
2)对灰度图进行二值化
3)对灰度图进行腐蚀
4)对腐蚀后的图进行膨胀还原
5)对膨胀后的图进行开运算
6)对图像进行轮廓识别

2.识别代码

import cv2
import numpy as np
 
 
def stackImages(scale, imgArray):
    """
        将多张图像压入同一个窗口显示
        :param scale:float类型,输出图像显示百分比,控制缩放比例,0.5=图像分辨率缩小一半
        :param imgArray:元组嵌套列表,需要排列的图像矩阵
        :return:输出图像
    """
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver
 
 
'1. 初始操作'
src = cv2.imread("coins.png")
img = src.copy()

'2. 图像预处理——灰度化'
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
'3. 图像预处理——二值化'
ret, thresh = cv2.threshold(gray, 135, 255,1)#(原图、阈值、填充色、类型)cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU
 
'4. 图像预处理——消除特有噪声(形态学变换)'
#腐蚀
kernel1 = np.ones((7, 7), np.uint8)
erosion = cv2.erode(thresh, kernel1, iterations=3)
# 膨胀
dilate1 = cv2.morphologyEx(erosion, cv2.MORPH_DILATE, (3,3), iterations=3)
# 开运算
opening = cv2.morphologyEx(dilate1, cv2.MORPH_CLOSE, kernel, iterations=1)



 
'根据距离变换的性质,经过简单的运算,即可用于细化字符的轮廓和查找物体质心(中心)。'
'5. 寻找前景区域——分离连接物体distanceTranform()参数含义:1)二值图像     2)距离变换类型   3)距离变换的掩膜模板'
# DIST_L2:简单欧几里得距离 Δ = sqrt((x1 - x2)² + (y1 - y2)²)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 3)
 
'6. 找到未知区域'
ret, sure_fg = cv2.threshold(dist_transform, 0.35 * dist_transform.max(), 255, 0)
print(ret)
sure_fg = np.uint8(sure_fg)
 
'7. 找到硬币中心(轮廓查找)findContours()参数含义:1)8位图像   2)轮廓查找模式    3)查找近似方法'
contours, hierarchy = cv2.findContours(sure_fg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:]
 
'8. 绘制硬币中心(轮廓绘制)drawContours()参数含义:1)原图     2)轮廓点坐标   3)轮廓索引    4)线条颜色  5)线条粗细'
cv2.drawContours(img, contours, -1, (0, 0, 255), 3)
 
'9. 完成显示'
cv2.putText(img, "count:{}".format(len(contours)), (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
cv2.putText(src, "srcImg", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
cv2.putText(gray, "gray", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
cv2.putText(thresh, "thresh", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
cv2.putText(dilate, "open", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
cv2.putText(sure_fg, "fg", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
 
imgStack = stackImages(0.7, ([src, gray, thresh], [erosion, opening, img]))
cv2.imshow("imgStack", imgStack)
cv2.waitKey(0)

3.识别效果

在这里插入图片描述

四、条形码识别

1.识别原理

识别原图:
在这里插入图片描述
首先还是对图片进行灰度化
在这里插入图片描述
对灰度化的图片进行二值化,将二值化的阈值设高即可过滤除条形码以外的文字点。
在这里插入图片描述
闭运算(横向长条形核填充)
在这里插入图片描述
腐蚀(在纵向腐蚀)
在这里插入图片描述
标记函数识别
在这里插入图片描述

3.识别代码

# 导入必要的包/库
import numpy as np
import argparse
import imutils
from pyzbar import pyzbar
import cv2
def stackImages(scale, imgArray):
    """
        将多张图像压入同一个窗口显示
        :param scale:float类型,输出图像显示百分比,控制缩放比例,0.5=图像分辨率缩小一半
        :param imgArray:元组嵌套列表,需要排列的图像矩阵
        :return:输出图像
    """
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver



#读取图片
src = cv2.imread("TXM.jpg")
img = src.copy()

#灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#高斯滤波
gauss = cv2.GaussianBlur(gray, (3, 3), 1)

#Sobel算子梯度差
sobel_x = cv2.Sobel(gauss, cv2.CV_64F, 1, 0, ksize=-1)
sobel_y = cv2.Sobel(gauss, cv2.CV_64F, 0, 1, ksize=-1)
Sobel=cv2.subtract(sobel_x,sobel_y)
Sobel = cv2.convertScaleAbs(Sobel)

# sobel_y = cv2.convertScaleAbs(sobel_y)
# Sobel = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)

#均值方波
blur = cv2.blur(Sobel, (5,5))

#二值化,大幅度降低条码以外的杂物
ret, thresh = cv2.threshold(blur, 254, 255, cv2.THRESH_BINARY )//阈值很高,除杂就高



#闭运算(横向长条形核填充
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (100, 1))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

#腐蚀(在纵向腐蚀
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
close1 = cv2.erode(close,kernel2, iterations = 4)


#膨胀扩大条形码原区域
kernel3 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
close2 = cv2.dilate(close1, None, iterations = 4)

#绘制条形码区域
contours = cv2.findContours(close2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
c = sorted(contours, key = cv2.contourArea, reverse = True)[0]
rect = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img, [box], -1, (0,0,255), 10)



cv2.putText(src, "src_img", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0,255), 3)
cv2.putText(gray, "gray", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0,255), 3)
cv2.putText(Sobel, "Sobels", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0,255), 3)
cv2.putText(thresh, "thresh", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 255, 0), 3)
cv2.putText(close, "close", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 255, 0), 3)
cv2.putText(close1, "close1", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 3)
cv2.putText(close2, "close2", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 3)
cv2.putText(img, "result", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 3)

barcodes = pyzbar.decode(src)
for barcode in barcodes:
    barcodeData = barcode.data.decode("utf-8")
    cv2.putText(img, barcodeData, (390, 750), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 4)

imgStack = stackImages(0.3, ([src,gray,Sobel,thresh],[close, close1, close2,img]))
cv2.imshow("imgStack", imgStack)
cv2.waitKey(0)

3.识别效果

在这里插入图片描述

参考

https://blog.csdn.net/weixin_41666747/article/details/101729776?
https://blog.csdn.net/qq_47281915/article/details/121640725?spm=1001.2014.3001.5501
https://blog.csdn.net/weixin_45602979/article/details/108831760

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值