OpenCV—Python Numpy数组(像素点)操作

一、遍历图片三个通道像素点,并修改相应的RGB

def access_pixels(image):
    print(image.shape)
    height = image.shape[0]
    width = image.shape[1]
    channels = image.shape[2]
    print("width: %s  height: %s  channels: %s"%(width, height, channels))
    for row in range(height):
        for col in range(width):
            for c in range(channels):
                pv = image[row , col, c]              #获取每个像素点的每个通道的数值
                image[row, col, c]=255 - pv           #灰度值是0-255   这里是修改每个像素点每个通道灰度值
    cv2.imshow("Reverse_phase_image",image)
    
if __name__ =="__main__":
    src=cv2.imread('555.png')                          #默认彩色读入
    cv2.imshow('original_image', src)                  #显示图像

    t1 = cv2.getTickCount()                            #GetTickcount函数返回从操作系统启动到当前所经过的毫秒数
    access_pixels(src)
    t2 = cv2.getTickCount()
    time = (t2-t1)/cv2.getTickFrequency()              #getTickFrequency函数返回CPU的频率,就是每秒的计时周期数
    print("time : %s ms"%(time*1000) )                 #输出运行时间
    cv2.waitKey(0)
    cv2.destroyAllWindows()

OpenCV—Python Numpy数组(像素点)操作_第1张图片

测试如何高效遍历像素

我本来想如何加速opencv-python的遍历像素效率,唯一能够稍微加快的方式是:先遍历小的数据范围,然后遍历大的数据范围。这样才能使遍历的速度有所加快。也就是说以下两种方式效果一样。

通过下述代码发现,最好不要通过遍历像素来操作图像,我们可以用numpy的矩阵运算。
若是C++代码,可以使用C语言的指针来遍历,通过指针操作像素的地址来操作对应数字会大大加速运算。

import cv2
import time
import numpy as np


# 遍历依次为通道,高,宽。
def inverse(image):
    height = image.shape[0]
    width = image.shape[1]
    channels = image.shape[2]
    pixel_data = np.array(image, dtype = np.uint8)
    for c in range(channels):
        for row in range(height):
            for col in range(width):
                level = pixel_data[row, col, c]
                pixel_data[row, col, c] = 255 - level
    return pixel_data


def inverse2(image):
    height,width = image.shape[:2]
    channels = image.shape[2]
    for c in range(channels):
        for row in range(height):
            for col in range(width):
                level = image[row, col, c]
                image[row, col, c] = 255 - level
    return image

if __name__ == '__main__':
    imgpath = r'C:\Users\xxxx\Desktop\201920100013253001_30302_01.jpg'
    image = cv2.imread(imgpath)
    print(image.shape)
    print(image.size)
    print(image.dtype)

    start1 = time.time()
    image1 = inverse(image)
    end1 = time.time()

    start2 = time.time()
    image2 = inverse2(image)
    end2 = time.time()

    print('cost_time1:',end1 - start1)
    print('cost_time2:', end2 - start2)
    cv2.imshow("inverse1 image", image1)
    cv2.imshow("inverse2 image", image2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
'''
(1732, 2309, 3)
11997564
uint8
cost_time1: 17.330647706985474
cost_time2: 17.001970291137695

Process finished with exit code 0
'''

二、非赋值修改像素

def get_bin_table(threshold=140):  #二值化图片(非函数,直接操作像素,简便快速)
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    return table

去除二值化后孤立点

OpenCV—Python Numpy数组(像素点)操作_第2张图片

def sum_9_region(img, x, y):
    """
    9邻域框,以当前点为中心的田字框,黑点个数
    :param x:
    :param y:
    :return:
    """
    # todo 判断图片的长宽度下限
    cur_pixel = img.getpixel((x, y))  # 当前像素点的值
    width = img.width
    height = img.height

    if cur_pixel == 1:  # 如果当前点为白色区域,则不统计邻域值
        return 0

    if y == 0:      # 第一行
        if x == 0:  # 左上顶点,4邻域
            # 中心点旁边3个点
            sum = cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 4 - sum
        elif x == width - 1:  # 右上顶点
            sum = cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1))

            return 4 - sum
        else:  # 最上非顶点,6邻域
            sum = img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 6 - sum
    elif y == height - 1:  # 最下面一行
        if x == 0:  # 左下顶点
            # 中心点旁边3个点
            sum = cur_pixel \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x, y - 1))
            return 4 - sum
        elif x == width - 1:  # 右下顶点
            sum = cur_pixel \
                  + img.getpixel((x, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y - 1))

            return 4 - sum
        else:  # 最下非顶点,6邻域
            sum = cur_pixel \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x, y - 1)) \
                  + img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x + 1, y - 1))
            return 6 - sum
    else:  # y不在边界
        if x == 0:  # 左边非顶点
            sum = img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 6 - sum
        elif x == width - 1:  # 右边非顶点
            # print('%s,%s' % (x, y))
            sum = img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1))

            return 6 - sum
        else:  # 具备9领域条件的
            sum = img.getpixel((x - 1, y - 1)) \
                  + img.getpixel((x - 1, y)) \
                  + img.getpixel((x - 1, y + 1)) \
                  + img.getpixel((x, y - 1)) \
                  + cur_pixel \
                  + img.getpixel((x, y + 1)) \
                  + img.getpixel((x + 1, y - 1)) \
                  + img.getpixel((x + 1, y)) \
                  + img.getpixel((x + 1, y + 1))
            return 9 - sum

你可能感兴趣的:(OpenCV,计算机视觉)