python 遥感图像处理 显著性检测 过滤背景 HC法(像素颜色欧式距离法)以及图片的二值化、模糊处理和快速像素替换

在图像处理中,过滤背景即保留图像的高频信息可以有效地提升处理速度,提高计算机识别目标的精度,用到显著性检测算法可以较好地实现这也过程,接下来我将对这一过程进行阐述:

一、HC法

设矩阵A和矩阵B分别代表两个不同的颜色那么它们之间的欧式距离(代码表示)为:

matC=(matA-matB)
length=numpy.linalg.norm(matC)

即两个矩阵相减后形成的矩阵的欧式范数(也即是几何上的距离)

当然这个是HC法的定义,真正进行图像处理的时候是不会直接用这个的,而是先计算图片的像素直方图,然后再对图片的像素进行替换,形成显著性检测图像。

二、获得图像直方图以及各颜色欧式距离

使用OpenCV的函数以及matplotlib可以快速获得直方图以及绘制,并以此获得各个颜色对于其他颜色的欧式距离。

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

mat=cv2.imread('mat.jpg')#读取图片

def get_hist(mat):
	hist=cv2.calcHist([mat],[0],None,[256],[0,256])#获取直方图的一维向量
	a=np.zeros(256)#生成一个256长度的向量
	for i in range(256):	#对所有值进行遍历
	    for j in range(256):
	        a[i]+=(i-j)**2*hist[j]#每次加上与这个像素的距离平凡并乘以像素数为总和
	a=np.sqrt(a)#开方处理
	a=a*255/np.max(a)-0.001#缩小到255以内
	gray_mat=a.astype(np.uint8)#转换成8位
	print(gray_mat)#验证
	return norm_mat#返回各个颜色的范数矩阵

三、对图片进行遍历以及像素快速替换

将图片的所有值进行替换,形成一个显著性检测图像。

def saliency_img(img_mat,norm_mat):
	########################对图像的每个像素进行遍历处理,将每个像素进行替换
	for i in range(img_mat.shape[0]): 
	    for j in range(img_mat.shape[1]):
	        c=img_mat[i][j].astype(np.uint8)#转换成八位
	        b[i][j]=norm_mat[c]
	########################
	b=b.astype(np.uint8)
	print(b)
	cv2.imshow('b',b)#显示图片
	cv2.waitKey(0)
	cv2.destroyAllWindows()
	return b#返回显著性检测矩阵

当然,大家得知道一个原则,在图片处理中,要尽量减少FOR循环的使用,尽量对图片进行矢量化操作,对像素进行替换的时候使用numpy.where()函数很好。


注释:
(1)numpy.where(condition,if_true,if_false)若condition为1执行if_true
假为if_false

(2)for i ,gray in enumerate(a): 这个远比for in range快
print(i,gray)
等价于
for i in range(a.shape[0]):
print(i,a[i])


以下是上面代码的另一种写法:

def saliency_img(img_mat,norm_mat):
	############################以下为不同之处
	b=img_mat
	for i, norm in enumerate(norm_mat):
		b=np.where(b==i,norm,b)
	############################
	saliency_img=b.astype(np.uint8)
	cv2.imshow('b',saliency_img)#显示图片
	cv2.waitKey(0)
	cv2.destroyAllWindows()
	return saliency_img#返回显著性检测矩阵

上面的代码可以说提高了非常多的速度,同时压缩了图像处理的时间

四、直方图均衡化和模糊处理(双边滤波)以及二值化

opencv的直方图均衡化有两种方法:
1、普通直方图均衡化(对较量和较暗的图像很好):

def equalize(img_mat):
    cl1=cv2.equalizeHist(img_mat)
    cv2.imshow('1',cl1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return cl1

2`、有限对比适应性直方图均衡化(可以较好的保留细节,但是较暗图片处理不太好)

def gethist_patch(img_mat):
    clahe=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
    cl1=clahe.apply(img_mat)
    cv2.imshow('1',cl1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

然后是双边滤波图像处理:

img=cv2.bilateralFilter(img,9,75,75)

图像的二值化(不用opencv):

img=np.where(img>255*2/3,255,0)#大于255的三分之二的为显著区域

五、显著性检测函数(合并一二)

def visual_saliency_detection(mat):
    hist = cv2.calcHist([mat], [0], None, [256], [0, 256])  # 获取直方图的一维向量
    a = np.zeros(256)  # 生成一个256长度的向量
    for i in range(256):  # 对所有值进行遍历
        for j in range(256):
            a[i] += (i - j) ** 2 * hist[j]  # 每次加上与这个像素的距离平凡并乘以像素数为总和
    a = np.sqrt(a)  # 开方处理
    a = a * 255 / np.max(a) - 0.001  # 缩小到255以内
    a = a.astype(np.uint8)  # 转换成8位
    print(a)
    b=mat
    for i, gray in enumerate(a):
        b=np.where(b==i,gray,b)
    b=b.astype(np.uint8)
    cv2.imshow('b',b)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return b

六、实验现象

原图像
在这里插入图片描述
显著性检测图像
在这里插入图片描述
二值化图像
在这里插入图片描述
看起来也许效果比较差,但是如果用在背景比较干净的图里效果是很好的

发布了11 篇原创文章 · 获赞 3 · 访问量 826

猜你喜欢

转载自blog.csdn.net/qq_44930937/article/details/104250558