kad*_*ina 20 python image-processing python-2.6
我必须在python中编写一个测试用例来检查jpg图像是彩色还是灰度.任何人都可以告诉我,如果有任何方法可以安装额外的库,如opencv吗?
sup*_*ind 13
可以按如下方式完成:
from scipy.misc import imread, imsave, imresize
image = imread(f_name)
if(len(image.shape)<3):
print 'gray'
elif len(image.shape)==3:
print 'Color(RGB)'
else:
print 'others'
Run Code Online (Sandbox Code Playgroud)
Ale*_*nko 13
使用 numpy 功能和 opencv 有更多 pythonic 方式:
import cv2
def isgray(imgpath):
img = cv2.imread(imgpath)
if len(img.shape) < 3: return True
if img.shape[2] == 1: return True
b,g,r = img[:,:,0], img[:,:,1], img[:,:,2]
if (b==g).all() and (b==r).all(): return True
return False
Run Code Online (Sandbox Code Playgroud)
joa*_*000 11
扩展@gat答案:
import Image
def is_grey_scale(img_path):
img = Image.open(img_path).convert('RGB')
w,h = img.size
for i in range(w):
for j in range(h):
r,g,b = img.getpixel((i,j))
if r != g != b: return False
return True
Run Code Online (Sandbox Code Playgroud)
基本上,检查每个像素是否是灰度(R == G == B)
为了更快地处理,最好使用ImageChops避免每个像素上的循环(但是为了确保图像是真正的灰度,我们需要比较每个像素上的颜色而不能仅使用总和):
from PIL import Image,ImageChops
def is_greyscale(im):
"""
Check if image is monochrome (1 channel or 3 identical channels)
"""
if im.mode not in ("L", "RGB"):
raise ValueError("Unsuported image mode")
if im.mode == "RGB":
rgb = im.split()
if ImageChops.difference(rgb[0],rgb[1]).getextrema()[1]!=0:
return False
if ImageChops.difference(rgb[0],rgb[2]).getextrema()[1]!=0:
return False
return True
Run Code Online (Sandbox Code Playgroud)
对于灰度图像,某一像素中的所有通道都是相等的(如果只有一个通道,那么就不会有问题)。因此基本上,您可以列出所有像素及其三个通道值,以检查每个像素的所有三个通道是否相等。
Image.getcolors()返回未排序的(计数、像素)值列表。
im = Image.open('path_to_image.whatever')
color_count = im.getcolors()
Run Code Online (Sandbox Code Playgroud)
如果len(color_count)超过 256(默认最大值),此函数返回 None,这意味着您的像素列表中有超过 256 种颜色选项,因此它是彩色图像(灰度只能有 256 种颜色(0,0,0))(255,255,255)。
所以之后你只需要:
if color_count:
# your image is grayscale
else:
# your images is colored
Run Code Online (Sandbox Code Playgroud)
请注意,这仅在使用默认参数值 时才有效getcolors()。
文档:https ://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getcolors
快速结果的性能增强:由于许多图像具有黑色或白色边框,您希望通过从 im 中采样一些随机 i,j 点并测试它们来更快地终止吗?或者使用模运算来遍历图像行。首先我们采样(-无替换)说 100 个随机 i,j 点;在不太确定的情况下,我们会对其进行线性扫描。
使用自定义迭代器 iterpixels(im)。我没有安装 PIL,所以我无法测试这个,这是大纲:
import Image
def isColor(r,g,b): # use tuple-unpacking to unpack pixel -> r,g,b
return (r != g != b)
class Image_(Image):
def __init__(pathname):
self.im = Image.open(pathname)
self.w, self.h = self.im.size
def iterpixels(nrand=100, randseed=None):
if randseed:
random.seed(randseed) # For deterministic behavior in test
# First, generate a few random pixels from entire image
for randpix in random.choice(im, n_rand)
yield randpix
# Now traverse entire image (yes we will unwantedly revisit the nrand points once)
#for pixel in im.getpixel(...): # you could traverse rows linearly, or modulo (say) (im.height * 2./3) -1
# yield pixel
def is_grey_scale(img_path="lena.jpg"):
im = Image_.(img_path)
return (any(isColor(*pixel)) for pixel in im.iterpixels())
Run Code Online (Sandbox Code Playgroud)
(我的原话也是如此,首先你检查 JPEG 头,偏移量 6:分量数(1 = 灰度,3 = RGB)。如果它是 1 = 灰度,你已经知道答案,而无需检查单个像素。)
我遇到了类似的情况,我尝试了以下方法:
IMREAD_UNCHANGED和检查 image.shape 进行读取这两种方法在我的数据集中只获得了 53% 的准确率。我必须放宽检查不同通道中像素的条件,并创建一个比率将其分类为灰色或彩色。通过这种方法,我的数据集准确率达到 87.3%。
这是对我有用的逻辑:
import cv2
import numpy as np
###test image
img=cv2.imread('test.jpg')
### splitting b,g,r channels
b,g,r=cv2.split(img)
### getting differences between (b,g), (r,g), (b,r) channel pixels
r_g=np.count_nonzero(abs(r-g))
r_b=np.count_nonzero(abs(r-b))
g_b=np.count_nonzero(abs(g-b))
### sum of differences
diff_sum=float(r_g+r_b+g_b)
### finding ratio of diff_sum with respect to size of image
ratio=diff_sum/img.size
if ratio>0.005:
print("image is color")
else:
print("image is greyscale")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27020 次 |
| 最近记录: |