零蚀
直方图
-
直方图的构建
- 我们一般会用直方图来直观的统计像素的分布,直方图可以帮助我们分析和修正图片(直方图一般是对一个色值进行统计,所以大部分的样例都是灰度图)。具体的代码如下:
import matplotlib.pyplot as plt src = cv.imread("../source/android.png", cv.IMREAD_GRAYSCALE) height = src.shape[0] width = src.shape[1] count = np.zeros(256, np.int) # 遍历每一个灰度图 for rows in range(height): for cols in range(width): gray = src[rows, cols] count[gray] = count[gray] + 1 # 绘制直方图 # 构建x轴的数据 ,param 起始值 0 ,终止值 255 ,总数 256 x = np.linspace(0, 255, 256) y = count plt.bar(x, y, width=10, alpha=0.8, color="blue", label="灰度") plt.show()
- 使用直方图API,使用直方图API方式 有两种,第一种是通过opencv的方式。
import cv2 as cv import matplotlib.pyplot as plt src = cv.imread("../source/collapse.jpg") src2 = cv.imread("../source/android.png") """ 直方图API images 资源 channel 需要绘制的通道 mask 遮罩(只绘制白色区域,不绘制黑色区域) histSize 颜色值总数(对应的channel的每一个总数) range 范围 """ hist = cv.calcHist([src], [0], None, [256], [0, 255]) plt.plot(hist, color="blue") plt.show()
- 另外一种是通过降维的方式,来将数据保存在一个数组中,来显示数据的变化。
import cv2 as cv import matplotlib.pyplot as plt src = cv.imread("../source/collapse.jpg") """ 直方图API ravel 将二维数据降到一维数组中 bins 设置变量范围 """ plt.hist(src.ravel(),bins=256) plt.show()
-
直方图均衡化(gray)
- 由于直方图的点像一个个离散的点,这里所说的均衡化,就是将直方图的离散点,按照函数的线形变化规律,来让直方图有一定的变化坡度,从而使得图像更加具有柔和的变化。
import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 直方图 from numpy.core._multiarray_umath import ndarray src = cv.imread("../source/collapse.jpg") gray = cv.cvtColor(src, cv.COLOR_BGRA2GRAY) x = np.linspace(0, 255, 256) y = np.zeros(256, np.int) for row in range(gray.shape[0]): for col in range(gray.shape[1]): gray_value = gray[row, col] y[gray_value] = y[gray_value] + 1 # 累计概率直方图 radio = np.zeros(256, np.float) for index, value in enumerate(y): radio[index] = value / (gray.shape[0] * gray.shape[1]) plt.bar(x, radio, 0.9, color="green") plt.show() # 显示 累加概率直方图 # 累加 概率就是逐级将概率直方图的值相加, sum_value = 0 sum_radio = np.zeros(256, np.float) for index, value in enumerate(radio): sum_value += value sum_radio[index] = sum_value plt.bar(x, sum_radio, 0.9, color="blue") plt.show() # 累计概率计算当前的颜色值 dst = np.zeros(gray.shape, np.uint8) for m in range(gray.shape[0]): for n in range(gray.shape[1]): old_color = gray[m,n] # 获取像素对应的累计概率 radio_obtain = sum_radio[old_color] # 输入累计概率对应的值 dst[m, n] = 255 * radio_obtain cv.imshow("dst",dst) cv.imshow("gray",gray) cv.waitKey()
- 灰度图直方图API
import cv2 as cv src = cv.imread("../source/android.png",cv.IMREAD_GRAYSCALE) # 直方图均衡化API dst = cv.equalizeHist(src) cv.imshow("hist",dst) cv.waitKey()
- 彩色图片的直方图,分别绘制每个渠道的直方图
import cv2 as cv import matplotlib.pyplot as plt src = cv.imread("../source/collapse.jpg") # 获取每个渠道的数据 channel_data = cv.split(src) colors = ["red", "green", "blue"] for i in range(len(channel_data)): channel = channel_data[i] # channel.ravel = rows * cols plt.hist(channel.ravel(), bins=256, color=colors[i]) plt.show()
- 彩色直方图的均衡化,彩色图片的均衡化,就是将图像的每个通道进行均衡化之后,将数据合并成原来的数值。可以看出均衡化后的色彩比原色彩没有那么鲜亮了,整体暗淡了一些。
import cv2 as cv src = cv.imread("../source/collapse.jpg") # 获取每个渠道的数据 channel_data = cv.split(src) colors = ["red", "green", "blue"] channel = [] for i in range(len(channel_data)): channel.append(cv.equalizeHist(channel_data[i])) # 合并每个渠道的数据 dst = cv.merge(channel) cv.imshow("dst", dst) cv.waitKey()
-
直方图规定化
- 直方图的规定化,是将我们当前的图像的直方图,和目标的直方图的直方图一致,比如说我想将当前的图像的色调,改成目标图像的色调。下面将卡通图的色映射到女团的图片背景。
import cv2 as cv import matplotlib.pyplot as mp import numpy as np """ 计算原图的累计直方图 计算目标的累计直方图 计算两个直方图,灰度差异 根据最小差异,进行映射 """ def get_plot(src): # 普通的直方图 hist = cv.calcHist([src], [0], None, [256], [0, 255]) # mp.plot(hist) # mp.show() # 累计概率 width = src.shape[1] height = src.shape[0] rate = hist / (width * height) # 绘制累计直方图 sum_ratio = np.zeros(256, np.float) sum_value = 0 for i in range(256): sum_value = sum_value + rate[i] sum_ratio[i] = sum_value mp.plot(sum_ratio) mp.show() return sum_ratio src = cv.imread("../source/aaaa.png", cv.COLOR_BGR2GRAY) src_radios = get_plot(src) # 原图的累计概率直方图 aim = cv.imread("../source/ashin.jpg", cv.COLOR_BGR2GRAY) aim_radios = get_plot(aim) # 目标的累计概率 origin1 = cv.imread("../source/aaaa.png", cv.COLOR_BGR2GRAY) origin2 = cv.imread("../source/ashin.jpg", cv.COLOR_BGR2GRAY) # 比较两个直方图的的灰度差异最小值 indexColor = np.zeros(256, np.uint8) for i, src_v in enumerate(src_radios): min_v = 256 index = 0 for j, aim_v in enumerate(aim_radios): distance = np.abs(aim_v - src_v) if distance < min_v: min_v = distance index = j indexColor[i] = index w = src.shape[1] h = src.shape[0] for row in range(h): for col in range(w): gray_color = src[row, col] refer = indexColor[gray_color] src[row, col]=refer cv.imshow("origin1",origin1) cv.imshow("origin2",origin2) cv.imshow("src",src) cv.waitKey(0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z8GPsSgM-1604831883524)(media/16006001095056/16048316268932.jpg)]- 如果想对彩色图进行直方图的映射,那么我们就需要进行channle的融合。大体的逻辑和上面的一样。
帧提取
-
相机
- 摄像头的打开,如果是ubuntu的话,我们可以使用以下的方式打开摄像头。
# 打开摄像头(ubuntu) sudo cheese
- 通过opencv的方式打开摄像头
import cv2 as cv # 调用摄像头(0是前置,1是后置,如果传入路径就是打开视频) camera = cv.VideoCapture(0) print("是否打开摄像头=", camera.isOpened()) # 获取宽,高,帧率 width = camera.get(cv.CAP_PROP_FRAME_WIDTH) height = camera.get(cv.CAP_PROP_FRAME_HEIGHT) fps = camera.get(cv.CAP_PROP_FPS) while True: flag, frame = camera.read() if flag: cv.imshow("camera", frame) # 设置帧率为20 key = cv.waitKey(50) # 设置点击"空格键"来跳出循环 if key == 32: break
- 其实我们获取的这个frame就是对应着的src数据,我们可以对应的修改。(比如像下面一下,对图像进行均衡化)
channel_data = [] while True: flag, frame = camera.read() if flag: split = cv.split(frame) channel = len(split) channel_data.clear() for i in range(channel): data = cv.equalizeHist(cv.equalizeHist(split[i])) channel_data.append(data) dst = cv.merge(channel_data) cv.imshow("camera", dst)
- 视频的解析
camera = cv.VideoCapture("../source/earth.mp4") print(camera.isOpened()) w = camera.get(cv.CAP_PROP_FRAME_WIDTH) h = camera.get(cv.CAP_PROP_FRAME_HEIGHT) fps = camera.get(cv.CAP_PROP_FPS) while True: flag, frame = camera.read() if flag: cv.imshow("earth", frame) # 将视频的图片每一帧输出 cv.imwrite("picture{}".format(time.time())) key = cv.waitKey(int(1000 / fps)) if key == 32: break
🔗 前言
🔗 机器人视觉篇
🔗 NO.1 机器视觉 前言
🔗 NO.2 机器视觉 几何变化 & 特效处理
🔗 NO.4 机器视觉 人脸识别&色彩过滤
🔗 NO.5 机器人视觉 二值化 & 卷积
🔗 NO.6 机器人视觉 霍夫检测 & 边缘查找
🔗 NO.7 C++中使用Opencv
🔗 NO.8 C++ 直方图 & 卷积
🔗 NO.9 C++ 匹配 & 变化
🔗 NO.10 C++ 图像算法