[Question]
  [
## Challenge
Given an image of the sky, you must output the cloud cover in oktas. The image supplied will be an image file (the type is up to you) and the output should be to STDOUT.
## Oktas
In meteorology, an okta is a unit of measurement used to describe the amount of cloud cover at any given location such as a weather station. Sky conditions are estimated in terms of how many eighths of the sky are covered in cloud, ranging from 0 oktas (completely clear sky) through to 8 oktas (completely overcast).
The sky will always be a picture from around midday (so, blue sky, not red/night sky).
The colour of a cloud will always be a colour which follows the following pattern:
```
#ABCDEF
```
Where `AB >= C0`, `CD >= C0` and `EF >= C0`.
Or, in RGB:
```
(A, B, C)
```
Where `A >= 192`, `B >= 192` and `C >= 192`.
Here are the percentage coverages related to the oktas:
```
0%    - 0 oktas
12.5% - 1 okta
25%   - 2 oktas
37.5% - 3 oktas
50%   - 4 oktas
62.5% - 5 oktas
75%   - 6 oktas
87.5% - 7 oktas
100%  - 8 oktas
```
The percentages are the percentage of the image which is cloud.
If you the percentage cloud of your image is not a multiple of 12.5, you should round to the nearest.
## Output
The output should just be the okta number (you don't have to say the unit).
## Examples
***1 okta*** (18.030743615677714% cloud)
![](https://upload.wikimedia.org/wikipedia/commons/1/16/Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG)
***0 oktas*** (0.0% cloud)
![](https://1.bp.blogspot.com/-lstV3uZJbPM/UHhLG5_vqAI/AAAAAAAAHGw/Hr9GN52jasM/s1600/spanish-sky.jpeg)
***3 oktas*** (42.66319444444445% cloud)
[![](https://i.stack.imgur.com/qmRjN.jpg)](https://i.stack.imgur.com/qmRjN.jpg)  
(source: [hswstatic.com](https://s.hswstatic.com/gif/why-is-sky-blue-1.jpg))
***1 okta*** (12.000401814778645% cloud)
![](https://i.stack.imgur.com/KTBF5.jpg)
[**Python code used to calculate numbers**](https://gist.github.com/beta-decay/fbcdb6626c9ed50529596e78cd6dffc8)
## Winning
Shortest code in bytes wins.
  
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~18~~ 17 bytes
```
Yi191>3&A1eYm8*Yo
```
Example runs with the four provided images (sorry about preview quality; click for full resolution):
[![enter image description here](https://i.stack.imgur.com/YXPQ5.png)](https://i.stack.imgur.com/YXPQ5.png)
Or remove the last four characters to see the results without rounding:
[![enter image description here](https://i.stack.imgur.com/gw2rg.png)](https://i.stack.imgur.com/gw2rg.png)
### Explanation
```
Yi     % Implicitly input filename or URL. Read image. Gives an M×N×3 array
191>   % Does each entry exceed 191?
3&A    % True for 3rd-dim "lines" that only contain true. Gives an M×N matrix
1e     % Linearize (flatten) into a 1×L row vector, with L = M*N
Ym     % Mean of vector
8*     % Multiply by 8
Yo     % Round. Implicitly display
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~114~~ ~~110~~ 98 bytes
-4 bytes thanks to TheLethalCoder  
-12 bytes thanks to Ruud  
```
import PIL.Image as P
i=P.open(input()).getdata()
print round(8.*sum(min(x)>191for x in i)/len(i))
```
[Try it online!](https://tio.run/##FcsxCsMwDADAPa/QKHVwSaZ0aPdAB3/BECcV1JJwZEhf75Lbz37@UZl652JaHeLyDktJe4Z0QBz4GYNaFmSx5kgU9uxr8oQ0WGVxqNpkxTncjlawsOBJr/ExblrhBBZgun@vT9T7Hw "Python 2 – Try It Online")
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), 204 bytes
```
i->{int x=0,y=0,t=0,w=i.getWidth(),h=i.getHeight();for(;x<w;)for(y=0;y<h;){java.awt.Color c=new java.awt.Color(i.getRGB(x++,y++));if(c.getRed()>191&&c.getBlue()>191&&c.getGreen()>191)t++;}return 8*t/w/h;}
```
[Try it online!](https://tio.run/##VY/BasMwDIbvfQqfit2kyXrbcNNBB@t6GINtsMPYwYudWF1qF0duWkKePXPaMtaDkPT96ANtxF5M7U6ZjfzpYbuzDskmsMQjVEnhTY5gTTLho/@haDCBrSjVEIx2/ruCnOSVqGvyLMC0F1KjwND2FiTZBk7f0IEpP7@EK2vWPl7s86UvCuWUXA/KeG1QlcotgtB6CUYFa0Z6mC5aMEgO2U18DIWhmgySUuEHSNSUxfq8PikoNVLGC@soP8wbzoYpHPHjXHPW/v3wYCvrSJ4Z1ZBrSE@m19WSHqIoPkYRYxwKmp@okpQtZnez8fi0LyuvrsDKKWXOhGEU8c4p9M6Q2wmmTap51/M01bYhtba@kgRIZYUkqKEmYMj7@uV@1HX9Lw "Java (OpenJDK 8) – Try It Online") I always forget that TIO outputs STDERR to the debug tab.. Maybe it could like highlight red in case of an error?
[Answer]
# C#, ~~150~~ 146 bytes
```
b=>{int t=0,c=0,w=0,h;for(;w<b.Width;++w)for(h=0;h<b.Height;++t){var p=b.GetPixel(w,h++);if(p.R>191&p.G>191&p.B>191)c++;}return(int)(c/(t+0d)*8);}
```
*Saved 4 bytes thanks to @Ian H.*
Full/Formatted version:
```
using System.Drawing;
namespace System
{
    class P
    {
        static void Main()
        {
            Func<Bitmap, int> f = b =>
            {
                int t = 0, c = 0, w = 0, h;
                for (; w < b.Width; ++w)
                    for (h = 0; h < b.Height; ++t)
                    {
                        var p = b.GetPixel(w, h++);
                        if (p.R > 191 & p.G > 191 & p.B > 191)
                            c++;
                    }
                return (int)(c / (t + 0d) * 8);
            };
            string[] testCases =
            {
                @"Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG",
                @"spanish-sky.jpeg",
                @"why-is-sky-blue-1.jpg",
            };
            foreach (string testCase in testCases)
            {
                using (Bitmap bitmap = new Bitmap(testCase))
                {
                    Console.WriteLine(f(bitmap));
                }
            }
            Console.ReadLine();
        }
    }
}
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 200 bytes
```
$a=New-Object System.Drawing.Bitmap $args[0]
0..($a.Height-1)|%{$h=$_;0..($a.Width-1)|%{$i+=(("$($a.GetPixel($_,$h)|select R,G,B)"|iex)['R','G','B']-ge192).count-eq3}}
[int]($i/($a.Height*$a.Width)*8)
```
Gets input `$args[0]` as the full image file-path, constructs a `New` `Bitmap` object into `$a`. This is just the internal object name; it supports JPG, PNG, etc.
We then double-loop through the `.height` and then the `.width` of the image, touching each `pixel`. We pull out the `R,G,B` values and then select those that are `-g`reaterthanor`e`qual to `192` and make sure that `count` is `3` (i.e., all of them are white-ish). That Boolean result is added into our accumulator `$i`.
We then divide out to get the percentage, multiply it by `8` to get the number of oktas, and then `[int]` to get just an integer output. *(Note that this performs Banker's Rounding -- if that's not allowed it'll be several more bytes to change the rounding method.)*
[Answer]
# x86 Machine Code, 34 bytes
```
51
31 D2
AD
F7 D0
25 C0 C0 C0 00
75 01
42
E2 F3
C1 E2 03
DB 04 24
52
DB 04 24
DE F1
DB 1C 24
58
5A
C3
```
These bytes of code define a function that takes a bitmap input and returns an integer value indicating its oktas. [As in C](https://codegolf.meta.stackexchange.com/questions/13210/list-input-in-c-and-length-argument), arrays (like bitmaps) are represented as a pointer to the first element and a size/length. Thus, this function takes two parameters: the total number of pixels in the bitmap (rows × columns) and a pointer to the bitmap itself.
This code uses a custom register-based calling convention, where the bitmap pointer is passed in the `ESI` register and the bitmap size is passed in the `ECX` register. The result (oktas) is, per usual, returned in `EAX`.
As already stated above, the input is taken as a bitmap. Specifically, a 32-bpp format is used, in a little-endian format, but the alpha channel (highest-order byte) is ignored. This simplifies a lot of things, allowing us to simply iterate through each pixel and check its 32-bit RGB color value. A clever optimization is also used here. Instead of isolating each color component and checking whether it is >= 192, we just mask the entire 32-bit value by 0xC0C0C0 and test whether the result is >= 0xC0C0C0. This will evaluate to true for all "cloud" colors, and false for all "sky" (non-cloud) colors. Well, *I* thought it was clever! :-) It certainly saves a large number of bytes.
Therefore, in order to test this code, you will need to convert the input images to 32-bpp bitmaps. You cannot use Windows Paint for this, because it supports maximum of 24 bits-per-pixel. However, there are a number of other software solutions that can do it, such as Adobe Photoshop. I used [this free tool](https://pngtobmp32.codeplex.com), which converts a PNG to a 32-bpp BMP on Windows, meaning that you need only convert from JPEG to PNG (which Paint can do).
Other assumptions that I posit are eminently reasonable:
* The bitmap is assumed to have a size greater than 0 (*i.e.*, it is assumed to contain at least one pixel). This is reasonable because, when they sky is null, we have bigger problems than meteorology.
* The direction flag (`DF`) is assumed to be clear so that we will iterate correctly through the bitmap using the `LODSD` instruction. This is the same assumption made by most x86 calling conventions, so it seems fair. If you don't like it, add 1 byte to the count for a `CLD` instruction.
* The rounding mode for the x87 FPU is assumed to be set to round-to-nearest-even. This ensures that we get the correct behavior when we convert the number of oktas from a floating-point temporary to the final integer result, as verified by test case #4. This assumption is reasonable because this is the default state for the FPU *and* it is required to be maintained even in C code (where truncation is the default rounding behavior, forcing compilers that wish to be standards-compliant to generate inefficient code that changes the rounding mode, does the conversion, and then changes the rounding mode back).
**Ungolfed assembly mnemonics:**
```
; int ComputeOktas(void*    bmpBits  /* ESI */,
;                  uint32_t bmpSize  /* ECX */);
   push  ecx                  ; save size on stack
   xor   edx, edx             ; EDX = 0 (cloudy pixel counter)
CheckPixels:
   lodsd                      ; EAX = DS:[ESI]; ESI += 4
   not   eax
   and   eax, 0x00C0C0C0
   jnz   NotCloudy
   inc   edx
NotCloudy:
   loop  CheckPixels          ; ECX -= 1; loop if ECX > 0
   shl    edx, 3              ; counter *= 8
   fild   DWORD PTR [esp]     ; load original size from stack
   push   edx
   fild   DWORD PTR [esp]     ; load counter from stack
   fdivrp st(1), st(0)        ; ST(0) = counter*8 / size
   fistp  DWORD PTR [esp]     ; convert to integer, rounding to nearest even
   pop    eax                 ; load result
   pop    edx
   ret
```
Surely you haven't made it all this way down and are still wondering how the code works? :-)  
Well, it's pretty simple. We just iterate through the bitmap one 32-bit value at a time, checking to see if that pixel RGB value is "cloudy" or "not cloudy". If it's cloudy, we increment our pre-zeroed counter. At the end, we compute: cloudy pixels⁄total pixels × 8  
(which is equivalent to: cloudy pixels⁄total pixels ÷ 0.125).
I can't include a TIO link for this because of the need for input images. I can, however, provide you with the harness I used to test this on Windows:
```
#include <stdio.h>
#include <assert.h>
#include <Windows.h>
int main()
{
   // Load bitmap as a DIB section under Windows, ensuring device-neutrality
   // and providing us direct access to its bits.
   HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,
                                        TEXT("C:\\...\\test1.bmp"),
                                        IMAGE_BITMAP,
                                        0, 0,
                                        LR_LOADFROMFILE  | LR_CREATEDIBSECTION);
   assert(hBitmap != NULL);
   // Get the bitmap's bits and attributes.
   DIBSECTION dib;
   GetObject(hBitmap, sizeof(dib), &dib);
   assert(dib.dsBm.bmBitsPixel == 32);
   uint32_t cx = dib.dsBm.bmWidth;
   uint32_t cy = abs(dib.dsBm.bmHeight);
   uint32_t sz = cx * cy;
   assert(sz > 0);
   int oktas = ComputeOktas(sz, dib.dsBm.bmBits);
   printf("%d\n", oktas);
   return 0;
}
```
Be careful with this, though! As defined above, `ComputeOktas` uses a custom calling convention, which a C compiler will not respect. You need to add code at the top of the assembly language procedure to load values from the stack into the expected registers, *e.g.*:
```
mov  ecx, DWORD PTR [bmpSize]
mov  esi, DWORD PTR [bmpBits]
```
[Answer]
# C#, 313 bytes
```
namespace System.Drawing.Imaging{b=>{unsafe{int t=0,c=0,y=0,x,w=b.Width,h=b.Height;var d=b.LockBits(new Rectangle(0,0,w,h),(ImageLockMode)1,(PixelFormat)137224);for(;y<h;++y){var r=(byte*)d.Scan0+y*d.Stride;for(x=0;x<w*3;++t)if(r[x++]>191&r[x++]>191&r[x++]>191)c++;}b.UnlockBits(d);return(int)(c/(t+0d)/0.125);}}}
```
Obviously longer than my other answer but this one uses `LockBits` and `unsafe` code to directly access the image in memory; as such it is incredibly quick. I could probably remove the call to `UnlockBits` but it's more correct with it there.
Full/Formatted version:
```
namespace System.Drawing.Imaging
{
    class P
    {
        static void Main()
        {
            Func<Bitmap, int> f = b =>
            {
                unsafe
                {
                    int t = 0, c = 0, y = 0, x, w = b.Width, h = b.Height;
                    var d = b.LockBits(new Rectangle(0, 0, w, h), (ImageLockMode)1, (PixelFormat)137224);
                    for (; y < h; ++y)
                    {
                        var r = (byte*)d.Scan0 + y * d.Stride;
                        for (x = 0; x < w * 3; ++t)
                            if (r[x++] > 191 & r[x++] > 191 & r[x++] > 191)
                                c++;
                    }
                    b.UnlockBits(d);
                    return (int)(c / (t + 0d) / 0.125);
                }
            };
            string[] testCases =
            {
                @"Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG",
                @"spanish-sky.jpeg",
                @"why-is-sky-blue-1.jpg",
            };
            foreach (string testCase in testCases)
            {
                using (Bitmap bitmap = new Bitmap(testCase))
                {
                    Console.WriteLine(f(bitmap));
                }
            }
            Console.ReadLine();
        }
    }
}
```
[Answer]
# JavaScript, ~~83~~ 77 bytes
-6 bytes by *ETHproductions*
```
f=i=>(z=a=b=0,i.map(e=>{z=e<192||z;(++b%4)||((z||(a+=64))&&(z=0))}),a/b+1>>1)
```
## Inputs
[Picture #1](https://www.dropbox.com/s/8r7julq4drprz4d/1.jpg?dl=1)
[Picture #2](https://www.dropbox.com/s/po6xsob6nvxu4fq/2.jpg?dl=1)
[Picture #3](https://www.dropbox.com/s/4hvn9kix4v1bfad/3.jpg?dl=1)
[Picture #4](https://www.dropbox.com/s/sjf6xr6tixgjoem/4.jpg?dl=1)
## Demo
```
f=i=>(z=a=b=0,i.map(e=>{z=e<192||z;(++b%4)||((z||(a+=64))&&(z=0))}),a/b+1>>1)
window.onload = function(){
	var input = document.getElementById('input');
	input.addEventListener('change', handleFiles);
}
function handleFiles(e){
	var canvas = document.getElementById('canvas')
	var ctx = canvas.getContext('2d');
	var img = new Image;
	img.onload = function(){
		canvas.height = img.height
		canvas.width = img.width
		ctx.drawImage(img, 0,0);
		data = ctx.getImageData(0,0,canvas.width,canvas.height).data;
		console.log(f(data))//invoke f, send imageData as input
	}
	img.src = URL.createObjectURL(e.target.files[0]);
}
```
```
<input type="file" id="input"/><br>
<canvas id="canvas" style="max-width:400px"/>
```
[Answer]
# C (POSIX), 103 bytes
Assumes input as BMP file on stdin.
```
b,c,i,m=0xc0c0c0;main(){lseek(0,54,0);for(;read(0,&b,3);c+=(b&m)==m,i++);printf("%d",(i+16*c)/(2*i));}
```
[Answer]
# dc, 74 bytes
```
???*sa?[1+]ss[r1+r]st[?191<s]su0ddsd[0luxluxlux3=t1+dla>r]dsrxr8*la2/+la/p
```
Input is taken as a P3 ppm file, with all whitespace as newlines. Output is to STDOUT.
[Try it online!](https://tio.run/##bYkxCoAwDEX3HqUdbCqCgporuJcMxYwdJKng7StVR3n/wYfHe62IaDVhBEeqUcAJaYkIE8xKenpm5ejzeb3rlwKOc1qFWOWS0eYUOpdTd9S69SY0hsH4h/b@/NoN)
[Answer]
# JavaScript (ES6), 218 bytes
```
(a,c=document.createElement`canvas`,w=c.width=a.width,h=c.height=a.height,x=c.getContext`2d`)=>x.drawImage(a,0,0)||x.getImageData(0,0,w,h).data.reduce((o,_,i,d)=>o+(i%4|d[i++]<192|d[i++]<192|d[i]<192?0:1),0)/w/h*8+.5|0
```
Takes an `Image` object as input, which can be created from an `<image>` element.
[Test it out here on CodePen!](https://codepen.io/justinm53/pen/MvaLdM)
## Alternative
If input can be taken as flat array of RGBA values, with dimensions: **82 bytes**
```
(d,w,h)=>d.reduce((o,_,i)=>o+(i%4|d[i++]<192|d[i++]<192|d[i]<192?0:1),0)/w/h*8+.5|0
```
This input format is very similar to what [this answer on meta](https://codegolf.meta.stackexchange.com/a/9099/69583) suggests.
[Answer]
# Mathematica 89 bytes
The following binarizes the picture and determines the fraction of clouds, i.e. white pixels. Then it determines how many times .125 fits into the result. It returns the floor of that value.
```
o@i_:=⌊8Tr@Flatten[ImageData@MorphologicalBinarize[i,.932],1]/Times@@ImageDimensions@i⌋
```
]