投影直方图+图片二值化+颜色空间转换

概念:

一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,最常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(BINARIZATION)。

作用:

二值化的所用就是将图像分成黑和白,更加有利于做图像处理判别。
每个像素点表示一个灰阶,然后我们将高于某一灰阶像素全部显示成白色,低于某一灰阶的像素点显示成黑色。这样就完成了对一幅图像二值化处理。在实际应用中,例如说金属表面,良品在照明下显示为灰阶125,而有瑕疵的产品会产生低于灰阶125的像素点,假设产生的是70,然后你设定你的判别标准时100(以上为白色,以下为黑色),这时瑕疵显示的是黑色,你测量你得到区域内图像的黑色面积,瑕疵产品的话产生的黑色面积就较大,以此你可以判别这个产品是否是次品还是良品。

自适应二值化处理:

颜色空间转换:

opencv inrange():

可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!

直方图:

calcHist—计算图像直方图 函数原型:calcHist(images, channels, mask, histSize, ranges, hist=None, accumulate=None) images:图像矩阵,例如:[image] channels:通道数,例如:0 mask:掩膜,一般为:None histSize:直方图大小,一般等于灰度级数 ranges:横轴范围

灰度直方图计算:

#encoding:utf-8

#
#灰度图像直方图
#

from matplotlib import pyplot as plt
import cv2

image = cv2.imread("H:\\img\\lena.jpg")
cv2.imshow("Original",image)

#图像直方图
hist = cv2.calcHist([image],[0],None,[256],[0,256])

plt.figure()#新建一个图像
plt.title("Grayscale Histogram")#图像的标题
plt.xlabel("Bins")#X轴标签
plt.ylabel("# of Pixels")#Y轴标签
plt.plot(hist)#画图
plt.xlim([0,256])#设置x坐标轴范围
plt.show()#显示图像

计算投影直方图:

import numpy as np
# 计算横向或者竖向每列非白像素的个数,image:传入的图像; direction:0->列,1->行
def calculate_pixel(image, axis):
    """
    Calculate the sum of **black** pixel
    The input image should be binaried. ie. the value of each pixel should either be `n` or `0`,
    `n` is a non-negative constant.
    :param image: input image
    :param axis: calculate sum along this axis
    :return:
    """
    # 取反
    img_matrix = np.logical_not(image)
    img_matrix = img_matrix + 0
    # img_matrix = image // 255
    pixel_sum = np.sum(img_matrix, axis=axis)

    return pixel_sum

def project(img, direction='vertical'):
    """
    Do projection.
    :param img: A numpy array. source image.
    :param direction: `vertical` | `horizontal`
    :return: A numpy array with shape (1, )
    """
    assert direction in ('vertical', 'horizontal')
    return calculate_pixel(img, 1 if direction == 'horizontal' else 0)

def draw_projective_histogram(img, direction='both', histogram_height=100, histogram_background='white'):
    """
    1. Copy the input img array
    2. Do padding, on right, bottom or both, according to the `direction`
    3. Draw histogram

    > The original input image will not be changed.
    :param histogram_background:
    :param histogram_height:
    :param img: A numpy array, the source image.
    :param direction: `vertical` | `horizontal` | `both`(default)
    :return: A numpy array
    """
    background_color = 255 if histogram_background == 'white' else 0
    foreground_color = 255 - background_color

    def sum2histogram(sum_array, histogram_canvas):
        assert len(sum_array.shape) == 1, "a `sum_array` should have only one dimension"
        max_val = np.max(sum_array)
        for x, val in enumerate(sum_array):
            histogram_canvas[histogram_height - int(val / max_val * histogram_height):, x] = foreground_color

    img_height, img_width = img.shape
    container_height = img_height + (0 if direction == 'horizontal' else histogram_height)
    container_width = img_width + (0 if direction == 'vertical' else histogram_height)
    container = np.ones((container_height, container_width)) * background_color
    # copy image into container
    container[:img_height, :img_width] = img
    container = container.reshape((*container.shape, 1))

    if direction == 'both':
        vertical_sum = project(img, direction='vertical')
        sum2histogram(vertical_sum, container[img_height:, :img_width])
        horizontal_sum = project(img, direction='horizontal')
        sum2histogram(horizontal_sum, np.transpose(container[:img_height, img_width:], [1, 0, 2]))
    elif direction == 'vertical':
        vertical_sum = project(img, direction='vertical')
        sum2histogram(vertical_sum, container[img_height:, :img_width])
    elif direction == 'horizontal':
        horizontal_sum = project(img, direction='horizontal')
        sum2histogram(horizontal_sum, np.transpose(container[:img_height, img_width:], [1, 0, 2]))
    return container

投影直方图的平滑:

  • 采用以为卷积核

    img

    • 图中的输入的数据维度为8,过滤器的维度为5。与二维卷积类似,卷积后输出的数据维度为8−5+1=48−5+1=4。
    • 如果过滤器数量仍为1,输入数据的channel数量变为16,即输入数据维度为8×168×16。这里channel的概念相当于自然语言处理中的embedding,而该输入数据代表8个单词,其中每个单词的词向量维度大小为16。在这种情况下,过滤器的维度由55变为5×165×16,最终输出的数据维度仍为44。
    • 如果过滤器数量为nn,那么输出的数据维度就变为4×n4×n。
    • 一维卷积常用于序列模型,自然语言处理领域。
  • numpy.convolve(a, v, mode=‘full’)

    这是numpy函数中的卷积函数库   参数:     a:(N,) 输入的一维数组     b:(M,) 输入的第二个一维数组     mode: {‘full’, ‘valid’, ‘same’}参数可选     ‘full’ 默认值,返回每一个卷积值,长度是N+M-1,在卷积的边缘处,信号不重叠,存在边际效应。     ‘same’ 返回的数组长度为max(M, N),边际效应依旧存在。     ‘valid’  返回的数组长度为max(M,N)-min(M,N)+1,此时返回的是完全重叠的点。边缘的点无效。

参考网址:

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦