问题
I'm looking over a number of images with missing aspects, namely missing either red, green or blue channels (which have been removed accidentally by an automated process before I was give the images). I need to fine the valid images.
Is there a quick way of checking to see if an image has all three (R, G & B) channels? Alpha channels (if included) are ignored.
I've been using PIL up until this for image processing in Python point (I realise it might not be the way forward). I've not tried anything yet as I'm not sure the best way forward: My first guess, and this may be long winded would be to loop over every pixel and working out if all the Red, Green or Blue data is zero (presumed missing) However I 've a feeling there's a faster method.
回答1:
You can check pretty easily with ImageMagick if an image has a missing channel. It is installed on most Linux distros and is available for OSX and Windows - it also has Python bindings but for now, I am just using the command-line:
tl;dr
Multiply together the mean of the red, the mean of the green and the mean of the blue channel - if any one of them is zero, the answer will be zero so your test is quick and easy:
convert NormalImage.png -format '%[fx:mean.r*mean.g*mean.b]' info:
0.0284282
or
convert NoRed.jpg -format '%[fx:mean.r*mean.g*mean.b]' info:
0
Longer Version
Basically, you can get the image statistics like this:
identify -verbose main.png
Image: main.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 1790x4098+0+0
Units: Undefined
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 7335420
Red:
min: 0 (0)
max: 184 (0.721569)
mean: 139.605 (0.547471) <--- Useful
standard deviation: 76.5813 (0.300319)
kurtosis: -0.46531
skewness: -1.21572
entropy: 0.210465
Green:
min: 0 (0)
max: 115 (0.45098)
mean: 87.2562 (0.342181) <--- Useful
standard deviation: 47.864 (0.187702)
kurtosis: -0.465408
skewness: -1.21572
entropy: 0.223793
Blue:
min: 0 (0)
max: 51 (0.2)
mean: 38.6967 (0.151752) <--- Useful
standard deviation: 21.2286 (0.0832494)
kurtosis: -0.46556
skewness: -1.21571
entropy: 0.253787
Image statistics:
Overall:
min: 0 (0)
max: 184 (0.721569)
mean: 88.5193 (0.347134)
standard deviation: 53.5609 (0.210043)
kurtosis: 1.21045
skewness: 0.306884
entropy: 0.229348
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 1790x4098+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2016-05-04T12:09:37+01:00
date:modify: 2016-05-04T12:00:06+01:00
png:bKGD: chunk was found (see Background color, above)
png:IHDR.bit-depth-orig: 8
png:IHDR.bit_depth: 8
png:IHDR.color-type-orig: 2
png:IHDR.color_type: 2 (Truecolor)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 1790, 4098
png:sRGB: intent=0 (Perceptual Intent)
signature: 1b12ce9d2a18826aa215b7e8b87a050717572ed638a6be6332c741eddb36c0be
Artifacts:
filename: main.png
verbose: true
Tainted: False
Filesize: 942KB
Number pixels: 7.335M
Pixels per second: 73.35MB
User time: 0.090u
Elapsed time: 0:01.099
Version: ImageMagick 6.9.3-7 Q16 x86_64 2016-04-05 http://www.imagemagick.org
Or, if you like parsing JSON:
convert main.png json:
{
"image": {
"name": "main.png",
"format": "PNG",
"formatDescription": "Portable Network Graphics",
"mimeType": "image/png",
"class": "DirectClass",
"geometry": {
"width": 1790,
"height": 4098,
"x": 0,
"y": 0
},
"units": "Undefined",
"type": "TrueColor",
"endianess": "Undefined",
"colorspace": "sRGB",
"depth": 8,
"baseDepth": 8,
"channelDepth": {
"red": 8,
"green": 8,
"blue": 8
},
"pixels": 7335420,
"imageStatistics": {
"all": {
"min": "0",
"max": "184",
"mean": "88.5193",
"standardDeviation": "53.5609",
"kurtosis": "1.21045",
"skewness": "0.306884"
}
},
"channelStatistics": {
"red": {
"min": "0",
"max": "184",
"mean": "139.605",
"standardDeviation": "76.5813",
"kurtosis": "-0.46531",
"skewness": "-1.21572"
},
"green": {
"min": "0",
"max": "115",
"mean": "87.2562",
"standardDeviation": "47.864",
"kurtosis": "-0.465408",
"skewness": "-1.21572"
},
"blue": {
"min": "0",
"max": "51",
"mean": "38.6967",
"standardDeviation": "21.2286",
"kurtosis": "-0.46556",
"skewness": "-1.21571"
}
},
"renderingIntent": "Perceptual",
"gamma": 0.454545,
"chromaticity": {
"redPrimary": {
"x": 0.64,
"y": 0.33
},
"greenPrimary": {
"x": 0.3,
"y": 0.6
},
"bluePrimary": {
"x": 0.15,
"y": 0.06
},
"whitePrimary": {
"x": 0.3127,
"y": 0.329
}
},
"backgroundColor": "#FFFFFF",
"borderColor": "#DFDFDF",
"matteColor": "#BDBDBD",
"transparentColor": "#000000",
"interlace": "None",
"intensity": "Undefined",
"compose": "Over",
"pageGeometry": {
"width": 1790,
"height": 4098,
"x": 0,
"y": 0
},
"dispose": "Undefined",
"iterations": 0,
"compression": "Zip",
"orientation": "Undefined",
"properties": {
"date:create": "2016-05-04T12:09:37+01:00",
"date:modify": "2016-05-04T12:00:06+01:00",
"png:bKGD": "chunk was found (see Background color, above)",
"png:IHDR.bit-depth-orig": "8",
"png:IHDR.bit_depth": "8",
"png:IHDR.color-type-orig": "2",
"png:IHDR.color_type": "2 (Truecolor)",
"png:IHDR.interlace_method": "0 (Not interlaced)",
"png:IHDR.width,height": "1790, 4098",
"png:sRGB": "intent=0 (Perceptual Intent)",
"signature": "1b12ce9d2a18826aa215b7e8b87a050717572ed638a6be6332c741eddb36c0be"
},
"artifacts": {
"filename": "main.png"
},
"tainted": false,
"filesize": "942KB",
"numberPixels": "7.335M",
"pixelsPerSecond": "73.35MB",
"userTime": "0.090u",
"elapsedTime": "0:01.099",
"version": "ImageMagick 6.9.3-7 Q16 x86_64 2016-04-05 http://www.imagemagick.org"
}
}
Or, you can be more surgical and just get things that interest you:
convert main.png -format '%[fx:255*mean.r]' info:
139.605
回答2:
Pretty much any image processing library provides means for reading pixel values. The simplest and most efficient way is indeed iterating over all pixels checking if any value is 0 for all pixels.
Of course many libraries also provide convenient tools for extracting color planes and calculating average pixel values. But internally, they do nothing but iterating over pixels. How else should any algorithm know if all values are zero if not by checking every value? So your feeling is wrong, unless the pixel reading function is poorly implemented and the algorithm is using someething more efficient, which is quite unlikely.
So you're doing nothing wrong either way.
来源:https://stackoverflow.com/questions/36136637/validate-existance-of-rgb-channels