Python 将图像中颜色的不同阴影转换为一种颜色
我如何将浅灰色背景色(其阴影变化)转换为单一颜色,例如浅灰色?我想深灰色的背景色顶部嵌入是一个单一的颜色以及。到目前为止,我所做的是用两个最接近的颜色名称(“浅灰色”和“浅灰色”)分配这两个区域,并最小化每个像素的r、g、b的平方差之和,并从WebColor模块获得最接近的颜色Python 将图像中颜色的不同阴影转换为一种颜色,python,image,opencv,image-processing,rgb,Python,Image,Opencv,Image Processing,Rgb,我如何将浅灰色背景色(其阴影变化)转换为单一颜色,例如浅灰色?我想深灰色的背景色顶部嵌入是一个单一的颜色以及。到目前为止,我所做的是用两个最接近的颜色名称(“浅灰色”和“浅灰色”)分配这两个区域,并最小化每个像素的r、g、b的平方差之和,并从WebColor模块获得最接近的颜色 rd = (r_c - requested_color[0]) ** 2 gd = (g_c - requested_color[1]) ** 2 bd = (b_c - requested_color[2]) ** 2
rd = (r_c - requested_color[0]) ** 2
gd = (g_c - requested_color[1]) ** 2
bd = (b_c - requested_color[2]) ** 2
原始图像:
由python代码生成的图像:
您可以看到,沿着边界,我无法获得您在原始图像中看到的浅灰色。您要做的是称为阈值化 有关如何使用OpenCV和Python执行此操作的一般介绍,请参见: 我在这里修改了代码的一些参数:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.png',0)
img = cv2.medianBlur(img,7)
ret,th1 = cv2.threshold(img,160,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,31,5)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,31,5)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in xrange(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
正如您在生成的图像中所看到的,图像的问题在于背景强度的强烈变化。在不知道图像来源的情况下,我会从以下两个选项中的一个开始,然后再尝试通过软件解决此问题:
1.)获得更均匀的照明
2.)如果不可能,并且所有图像的照明都相同,则仅制作背景的空图像,并将其从其他图像中减去,以获得更均匀的照明
重要的是要了解这不是软件问题:在边界区域,背景比图像中间附近位置的结构更暗。您可以通过检查单个像素的灰度值来检查这一点。只有你的眼睛才能很好地补偿这一点。下面列出的自适应阈值技术试图找到合适的局部阈值,但这是有限制的。不过,您可能会找到更合适的参数,但我建议的第一件事是研究照明的均匀性
[编辑]
我在下面添加了一段额外的代码,用于处理图像,它允许您
- 使用滑块调整阈值
- 使用鼠标右键再次查看原始图像,检查 不同鼠标位置的灰度值,并通过单击鼠标右键 再次单击鼠标按钮,切换回阈值视图并使用灰度值 最后一个鼠标位置的值作为新阈值
感谢您提供此解决方案…非常有用。然而,我有一个关于阈值化图像细节的问题:尽管阈值化使图像在边界附近变得更好,但它使内部区域更亮(深灰色区域)。是否有可能从图像#2获得内部区域,从图像#3(或#4)获得边界区域?我需要首先更好地理解您的一些限制和意图:1)您是否有更多类似的图像要检查?如果是,你能提供一些吗?(涵盖变化方面)2)你在准确性方面的最终目标是什么,你想可视化吗,你想测量面积吗,你想找到质心吗…嗨…参考你的评论:1)我在问题的更新部分添加了两张图片。2) 我的目标是计算被深灰色占据的像素数(占图形总面积的分数)。关于更改图像的数组大小,我有一个问题:当前,阈值化后图像的输出数组大小
(1601043)
…有没有办法为阈值化后获得的输出数组提供自定义大小?有关cv2使用的函数的文档很少,并且缺少对所用变量的解释。输出与输入大小相同。您可以使用上面引用的教程中的resize函数cv2.resize()更改图像大小。
import cv2
import numpy as np
mode = ""
Schwelle =0
def nothing(x):
pass
def read_pixel(event,x,y,flags,param):
global mode, Schwelle
if event == cv2.EVENT_MOUSEMOVE:
if mode == "Analyse":
ix,iy = x,y
font = cv2.FONT_HERSHEY_SIMPLEX
img2=img.copy()
cv2.putText(img2,str(ix)+" "+str(iy)+": "+str(img[y,x]),(50,50), font, 1,(255,255,255),2,cv2.LINE_AA)
cv2.imshow('image',img2)
elif event == cv2.EVENT_RBUTTONDOWN:
if mode == "Analyse":
mode=""
Schwelle=img[y,x]
cv2.createTrackbar('Schwelle','image',Schwelle,255,nothing)
else:
mode = "Analyse"
elif event == cv2.EVENT_LBUTTONDOWN:
Schwelle= img[y,x]
img =cv2.imread('image.png',0)
cv2.namedWindow('image')
cv2.setMouseCallback('image',read_pixel)
cv2.createTrackbar('Schwelle','image',128,255,nothing)
while(1):
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
if mode != "Analyse":
Schwelle = cv2.getTrackbarPos('Schwelle','image')
ret,thresh1 = cv2.threshold(img,Schwelle,255,cv2.THRESH_BINARY)
cv2.imshow('image',thresh1)
cv2.destroyAllWindows()