Python+OpenCV实现图像边缘检测算子SOBEL、ROBERT

 在Jupyter Notebook上使用Python实现图像边缘检测算子SOBEL、ROBERT,这个过程中实现某些功能处理出来的图像可能会有点粗糙。关于opencv库的安装可以参考:Python下opencv库的安装过程与一些问题汇总

1.实现代码

import cv2
import numpy as np
import matplotlib.pyplot as plt

#实现图片反色功能
def PointInvert(img):
    height, width, _ = img.shape
    for i in range(height):
        for j in range(width):
            pi = img[i, j]
            img[i, j] = 255 - pi
return img

#读取原灰度图片
src_s=cv2.imread("dip_switch_02.bmp")
cv2.imshow("src_s", src_s)#将原图片命名为“src_s”显示出来
#图片反色
src=PointInvert(src_s)
cv2.imshow("src", src)#将图片src_s反色处理后命名为“src”并显示出来

#SOBEL算子
sobel = cv2.Sobel(src,cv2.CV_64F, 1, 1, ksize=7)
cv2.imshow("sobel", sobel)#将SOBEL算子处理后的图片src命名为“sobel”并显示出来
#图片反色
sobel2=PointInvert(sobel)
cv2.imshow("sobel2", sobel2)#将图片sobel反色处理后命名为“sobel2”并显示出来

#ROBERT算子
def Robert(img):
    h,w,_ = img.shape
    rob = [[-1,-1],[1,1]]
    for x in range(h):
        for y in range(w):
            if (y + 2 <= w) and (x + 2 <= h):
                imgChild = img[x:x+2, y:y+2, 1]
                list_robert = rob*imgChild
                img[x, y] = abs(list_robert.sum())# 求和加绝对值
    return img
robert = Robert(src)
cv2.imshow("robert", robert)#将ROBERT算子处理后的图片src命名为“robert”并显示出来

#图片反色
robert2=PointInvert(robert)
cv2.imshow("robert2", robert2)#将图片robert反色处理后命名为“robert2”并显示出来
cv2.waitKey(0)

 

2.运行结果

 

 

 

 

 

3.遇到的问题及解决方法

(1) 运行时出现:ValueError: too many values to unpack(expect 2)

出错代码:h,w = img.shape

出错原因:

首先了解img.shape[0]、[1]、[2]。

img.shape[0]:图像的垂直尺寸(高度)

img.shape[1]:图像的水平尺寸(宽度)

img.shape[2]:图像的通道数

在矩阵中,[0]就表示行数,[1]则表示列数。

由此可知,img.shape默认返回值个数为3个,而我没有指明缺失的参数。

解决方法:

此处未用到的参数为图像的通道数,使用_代表用不到的参数,将代码h,w = img.shape改为h,w,_ = img.shape。

 

(2) 运行时出现:ValueError: operands could not be broadcast together with shapes (2,2) (2,2,3)

出错代码:list_robert = rob*imgChild

出错原因:

经过网上搜索解决方法,发现是违反了ufunc的广播机制。广播机制如下:

当使用ufunc函数对两个数组进行计算时,ufunc函数会对这两个数组的对应元素进行计算,因此它要求这两个数组有相同的大小(shape相同)。如果两个数组的shape不同的话,会进行如下的广播(broadcasting)处理:

1)让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐。

2)输出数组的shape是输入数组shape的各个轴上的最大值。

3)如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。

4)当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值。

我们图片的shape是(h,w,c),而列表的shape是(x:x+2, y:y+2),根据规则1可知列表的shape拓展应为(x:x+2, y:y+2,1);由规则2可知输出数组的shape应为(h,w,c),列表的shape不满足规则3,所以出错。

解决方法:

将代码imgChild = img[x:x+2, y:y+2]改为imgChild = img[x:x+2, y:y+2, 1]。

猜你喜欢

转载自www.cnblogs.com/BIXIABUMO/p/12639418.html