使用 STD 对图像进行平滑处理
Smoothing Process Over an Image Using STD
import cv2
将 numpy 导入为 np
导入 scipy
导入 matplotlib.pyplot 作为情节
从 PIL 导入图像
从 skimage 导入 io
导入 glob
从 skimage 导入 io,img_as_float
img = cv2.imread(r"C:\Users\hoday\Desktop\GRAPE_IMG\GrapeBox.jpg", 1)
img = np.float32(img)
blue_img, green_img, red_img = cv2.split(img) #将图像分成3个通道 - BGR
频道 = [blue_img、green_img、red_img]
std_channels = []
频道中的频道:
lst = []
img_row = (channel.shape)[0]
img_col = (channel.shape)[1]
for row in range(1, img_row-1): #for 5X5 1--->2
for col in range(1, img_col-1): #for 5X5 1--->2
mask = channel[row-1:row+2, col-1:col+2] #for 5X5 ---> mask = channel[row-2:row+3, col-2:col+3]
lst.append(mask.std())
std_channel = np.array(lst)
std_channel = std_channel.reshape(img_row-2, img_col-2) #for 5X5 2--->4
std_channels.append(std_channel)
img_merged = cv2.merge(std_channels)
cv2.imwrite(r"C:\Users\hoday\Desktop\GRAPE_IMG\normalStd.png", img_merged)
你好,
我正在尝试遍历图像的像素并取出由 std 组成的新图像
就像下一个视频中所做的那样:
https://www.youtube.com/watch?v=ZoaEDbivmOE&t=80s
我将图像分成 3 个通道,并尝试为每个通道更新一个新数组,但是当我尝试 运行 代码时,我卡住了。例如,不是像预期的那样为 img[0:3, 0:3].std() 打印值 5.58,它打印的值是 1.28 - 现在这是 std 的值一个频道,但我想要一个与所有三个频道合并...
可能我没有以正确的方式合并频道,但我不知道我还能怎么做。
更新答案
您可以使用 Numba 将其降低到 1 毫秒以下:
#!/usr/bin/env python3
import cv2
import numba as nb
import numpy as np
import math
@nb.jit(nopython=True, parallel=True, fastmath=True)
def numbaStd(im):
# Allocate space for result
res = np.zeros_like(im)
h, w, c = im.shape
for row in nb.prange(1,h-1):
for col in range(1,w-1):
for band in range(c):
x0 = im[row-1,col-1,band]
x1 = im[row-1,col ,band]
x2 = im[row-1,col+1,band]
x3 = im[row ,col-1,band]
x4 = im[row ,col ,band]
x5 = im[row ,col+1,band]
x6 = im[row+1,col-1,band]
x7 = im[row+1,col ,band]
x8 = im[row+1,col+1,band]
mu = (x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8) / 9
S = (x0 - mu)**2
S += (x1 - mu)**2
S += (x2 - mu)**2
S += (x3 - mu)**2
S += (x4 - mu)**2
S += (x5 - mu)**2
S += (x6 - mu)**2
S += (x7 - mu)**2
S += (x8 - mu)**2
res[row,col,band] = math.sqrt(S/9)
return res
# Open image and make into Numpy array
im = cv2.imread('grapes.jpg', cv2.IMREAD_COLOR)
# Call Numba standard deviation
res = numbaStd(im)
# Optional block to contrast stretch result image
res[...,0] = 255.0*res[...,0]/res[...,0].max()
res[...,1] = 255.0*res[...,1]/res[...,1].max()
res[...,2] = 255.0*res[...,2]/res[...,2].max()
# Save result
cv2.imwrite("result.png", res)
# IPython timing
#%timeit numbaStd(im)
In [19]: %timeit numbaStd(im)
864 µs ± 20.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
原答案
您可以更简单地使用 SciPy generic_filter 在图像上传递 3x3 window,如下所示:
#!/usr/bin/env python3
import numpy as np
from PIL import Image
from scipy.ndimage import generic_filter
# Stddev filter
def stddev(P):
"""
We receive P[0]..P[8] with the pixels in the 3x3 surrounding window.
"""
return np.std(P)
# Open image and make into Numpy array
im = Image.open('paddington.png')
im = np.array(im)
# Run 3x3 stddev filter on one band/channel at a time
im[...,0] = generic_filter(im[...,0], stddev, (3, 3))
im[...,1] = generic_filter(im[...,1], stddev, (3, 3))
im[...,2] = generic_filter(im[...,2], stddev, (3, 3))
# Save result
Image.fromarray(im).save('result.png')
变成这样:
进入这个:
顺便说一下,您可以在终端中使用 ImageMagick 做同样的事情,而无需编写任何代码,如下所示:
magick paddington.png -separate -statistic standarddeviation 3x3 -combine result.png
import cv2
将 numpy 导入为 np 导入 scipy 导入 matplotlib.pyplot 作为情节 从 PIL 导入图像 从 skimage 导入 io 导入 glob 从 skimage 导入 io,img_as_float
img = cv2.imread(r"C:\Users\hoday\Desktop\GRAPE_IMG\GrapeBox.jpg", 1) img = np.float32(img)
blue_img, green_img, red_img = cv2.split(img) #将图像分成3个通道 - BGR
频道 = [blue_img、green_img、red_img] std_channels = []
频道中的频道:
lst = []
img_row = (channel.shape)[0]
img_col = (channel.shape)[1]
for row in range(1, img_row-1): #for 5X5 1--->2
for col in range(1, img_col-1): #for 5X5 1--->2
mask = channel[row-1:row+2, col-1:col+2] #for 5X5 ---> mask = channel[row-2:row+3, col-2:col+3]
lst.append(mask.std())
std_channel = np.array(lst)
std_channel = std_channel.reshape(img_row-2, img_col-2) #for 5X5 2--->4
std_channels.append(std_channel)
img_merged = cv2.merge(std_channels) cv2.imwrite(r"C:\Users\hoday\Desktop\GRAPE_IMG\normalStd.png", img_merged)
你好, 我正在尝试遍历图像的像素并取出由 std 组成的新图像 就像下一个视频中所做的那样:
https://www.youtube.com/watch?v=ZoaEDbivmOE&t=80s
我将图像分成 3 个通道,并尝试为每个通道更新一个新数组,但是当我尝试 运行 代码时,我卡住了。例如,不是像预期的那样为 img[0:3, 0:3].std() 打印值 5.58,它打印的值是 1.28 - 现在这是 std 的值一个频道,但我想要一个与所有三个频道合并...
可能我没有以正确的方式合并频道,但我不知道我还能怎么做。
更新答案
您可以使用 Numba 将其降低到 1 毫秒以下:
#!/usr/bin/env python3
import cv2
import numba as nb
import numpy as np
import math
@nb.jit(nopython=True, parallel=True, fastmath=True)
def numbaStd(im):
# Allocate space for result
res = np.zeros_like(im)
h, w, c = im.shape
for row in nb.prange(1,h-1):
for col in range(1,w-1):
for band in range(c):
x0 = im[row-1,col-1,band]
x1 = im[row-1,col ,band]
x2 = im[row-1,col+1,band]
x3 = im[row ,col-1,band]
x4 = im[row ,col ,band]
x5 = im[row ,col+1,band]
x6 = im[row+1,col-1,band]
x7 = im[row+1,col ,band]
x8 = im[row+1,col+1,band]
mu = (x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8) / 9
S = (x0 - mu)**2
S += (x1 - mu)**2
S += (x2 - mu)**2
S += (x3 - mu)**2
S += (x4 - mu)**2
S += (x5 - mu)**2
S += (x6 - mu)**2
S += (x7 - mu)**2
S += (x8 - mu)**2
res[row,col,band] = math.sqrt(S/9)
return res
# Open image and make into Numpy array
im = cv2.imread('grapes.jpg', cv2.IMREAD_COLOR)
# Call Numba standard deviation
res = numbaStd(im)
# Optional block to contrast stretch result image
res[...,0] = 255.0*res[...,0]/res[...,0].max()
res[...,1] = 255.0*res[...,1]/res[...,1].max()
res[...,2] = 255.0*res[...,2]/res[...,2].max()
# Save result
cv2.imwrite("result.png", res)
# IPython timing
#%timeit numbaStd(im)
In [19]: %timeit numbaStd(im)
864 µs ± 20.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
原答案
您可以更简单地使用 SciPy generic_filter 在图像上传递 3x3 window,如下所示:
#!/usr/bin/env python3
import numpy as np
from PIL import Image
from scipy.ndimage import generic_filter
# Stddev filter
def stddev(P):
"""
We receive P[0]..P[8] with the pixels in the 3x3 surrounding window.
"""
return np.std(P)
# Open image and make into Numpy array
im = Image.open('paddington.png')
im = np.array(im)
# Run 3x3 stddev filter on one band/channel at a time
im[...,0] = generic_filter(im[...,0], stddev, (3, 3))
im[...,1] = generic_filter(im[...,1], stddev, (3, 3))
im[...,2] = generic_filter(im[...,2], stddev, (3, 3))
# Save result
Image.fromarray(im).save('result.png')
变成这样:
进入这个:
顺便说一下,您可以在终端中使用 ImageMagick 做同样的事情,而无需编写任何代码,如下所示:
magick paddington.png -separate -statistic standarddeviation 3x3 -combine result.png