我必须确定图像是否是单色的。我的意思是单色不仅是黑色和白色..它可以是棕褐色,如红色或蓝色阴影,甚至混合红色和蓝色阴影(单色缩放)?
我认为我们可以说比例从黑色(0,0,0)到白色(255,255,255)但它不是线性的..它是每个颜色通道上的特定曲线
我希望我说得清楚:)
如果您想到这样的灰度图像:
图像中存在的所有 RGB 三元组都将位于连接 RGB[0,0,0] 的直线上或附近,即黑色到 RGB[255,255,255],即 RGB 颜色立方体中的白色:
所有单色图像都是这种情况 - 所有 RGB 三元组都将出现在 RGB 颜色立方体中的一条直线附近。在蓝晒法中,直线将穿过深蓝色和浅蓝色。在棕褐色图像中,直线将穿过棕色和浅棕色,而在红蓝双色调中,直线将连接 RGB 立方体内的红色和蓝色点。
让我们看一些图像及其散点图......
灰度
蓝晒法
双色调
棕褐色
我认为一种可能对您有用的技术是将一条直线拟合到图像的 RGB 颜色立方体中的点云,然后查看最小二乘误差,如果该误差很小,则这些点位于一条线上,你的图像是单色的。我认为该线称为“3D 正交距离回归 (ODR) 线” - 请参阅此处。
我现在已经尝试过数学了。基本上,我相信我可以计算三元组的 SVD 并获得 3 个主成分中每个主成分中包含的方差。如果所有 RGB 三元组都位于一条直线上,则第一个主成分中的所有方差都将沿着该线分布,并且将为 100%,第二个和第三个成分将为零。如果 RGB 三元组主要位于第一个分量中,第二个分量中的百分比较小,而第三个分量中没有,则意味着它们大部分落在一条线上,并且仅倾向于偏离该线的单个垂直方向,因此点云将看起来像一个长扁的椭圆形。如果第二个和第三个分量相当大,则点云为三维雪茄形状。如果第一个分量不包含非常显着的方差百分比,则 RGB 三元组不会落在一条直线上。
#!/usr/local/bin/python3
import sys
import numpy as np
from skimage import io
from skimage.transform import resize
if len(sys.argv) != 2:
sys.exit("Usage: mono.py filename")
path = sys.argv[1]
im = io.imread(path)
# Down-res image to make SVD time reasonable
im = resize(im,(128,128))
# Form list of all RGB triplets present in image
triplets = im.reshape(-1,3)
# Get mean on all axes
means = triplets.mean(axis=0)
# Calculate SVD
uu, dd, vv = np.linalg.svd(triplets - means)
# dd holds the variance in each of the PCA directions
# The key factor is what percentage of the variance is held in the first direction
PC1var = dd[0]*100./dd.sum()
PC2var = dd[1]*100./dd.sum()
PC3var = dd[2]*100./dd.sum()
print(f"PC1 variance: {PC1var}")
print(f"PC2 variance: {PC2var}")
print(f"PC3 variance: {PC3var}")
Run Code Online (Sandbox Code Playgroud)
针对我的测试图像运行上述代码给出的结果为 90% 以上,对于正常的非单色照片给出的值约为 60%。请在投入生产之前进行一些测试!
为了供我自己参考,我将三元组提取到 CSV 文件中,如下所示:
#!/usr/local/bin/python3
import numpy as np
from skimage import io
images = ["greyscale","tintype", "sepia", "duotone", "cyanotype"]
for i in images:
# Load image
im = io.imread(i + ".jpg")
# Form list of all RGB triplets
triplets = im.reshape(-1,3)
with open(i + ".dat",'w') as f:
for t in triplets:
f.write(f"{t[0]} {t[1]} {t[2]}\n")
Run Code Online (Sandbox Code Playgroud)
我用gnuplot绘制了 3-d 散点图,如下所示:
#!/usr/bin/env gnuplot --persist
set xrange [0:255]
set yrange [0:255]
set zrange [0:255]
set ticslevel 0
splot "cyanotype.dat" u 1:2:3 with points
Run Code Online (Sandbox Code Playgroud)
关键词:Python、图像处理、单色、氰基、tintype、双色调、灰度、Gnuplot、splot、3D、3-d、三元组、云。点云,RGB 颜色立方体。
| 归档时间: |
|
| 查看次数: |
1300 次 |
| 最近记录: |