Bitmap/Histogram: Difference between revisions

→‎{{header|Java}}: Replace horribly complicated code with a clean and nice solution
m (1-bit gray and save as PBM)
(→‎{{header|Java}}: Replace horribly complicated code with a clean and nice solution)
Line 658:
 
=={{header|Java}}==
<lang Java>import java.awt.image.BufferedImage;
This solution is based on JAVA 8 stream API
import java.io.File;
<lang Java>
import java.io.IOException;
package bitmap;
import javax.imageio.ImageIO;
 
public enum ImageProcessing {
import java.util.ArrayList;
;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public static void main(String[] args) throws IOException {
/**
BufferedImage img = ImageIO.read(new File("example.png"));
* Image processing functions such as histogram, grayscale,..
* here we assume we have a YUV image. so we process only luma component Y
* the histogram can be called on luma pixel only (values from 0 to 255)
* greyscale is done with a constant middle value of FullRange / 2 = 127
*/
public class ImageProc {
 
BufferedImage bwimg = toBlackAndWhite(img);
static final private Integer MAX_VAL = 255;
static final private Integer MIN_VAL = 0;
static final private Integer MID_RANGE = (MAX_VAL - MIN_VAL) >> 1;
private static Integer[] lumaHist(Integer[] luma,Integer length) {
// from input length, select a number of classes (intervalles )
// usually take sqrt(length)
if ((length == 0 )|| (luma == null)){
return null;
}
double stepd = Math.sqrt(length);
// define the interval width
int step = (int)stepd ;
Integer width = (int)(length / stepd);
// define step Lists containing only values in one interval
// done with a loop generating a new list that discard lower part
// the luma buff is fist sorted to split the array correctly
// only values greater than width are kept in a new list
 
ImageIO.write(bwimg, "png", new File("example-bw.png"));
List<Integer> interv[] = new ArrayList[step];
}
Integer hist[] = new Integer[step];
interv[0] = Arrays.stream(luma)
.parallel()
.sorted()
.filter(value -> value >= width)
.collect(Collectors.toList());
hist[0] = length - interv[0].size();
// here due to a lambda expression limitation
// we can not modify the width value. (should be a final var)
// so we decrease each reaming values with width, and store in a new list
// the filter is than the same across iterations
// histogram is computed in the same loop: the number of data for the interval
// is equal to the previous list size minus the new list size
for (int i =1; i < step; i++){
 
private static int luminance(int rgb) {
interv[i] = interv[i-1].stream()
int r = .map(valuergb ->> value16) -=& width)0xFF;
int g = .filter(valuergb -> value >= width8) & 0xFF;
int b = rgb & 0xFF;
.collect(Collectors.toList());
return (r + b + hist[i] = interv[i-1].size(g) -/ interv[i].size()3;
}
return hist;
}
 
private static Integer[]BufferedImage blackAndWhitetoBlackAndWhite(Integer[] luma,IntegerBufferedImage lengthimg) {
int width = img.getWidth();
int height = List<Integer> bwPict img.getHeight();
// compute the average value of the stream
// need to transform the List<Integer> in List<String> to transform in int !!!
double average;
average = Stream.of(luma).map(i -> i.toString())
.mapToInt(Integer::parseInt)
.average()
.getAsDouble();
System.out.println("Average value : " +average);
// compare each value with the average
// if less set to 0 (black) if more, set to 255 (black)
bwPict= Arrays.stream(luma)
.parallel()
.map(value -> (value > average) ?MAX_VAL: MIN_VAL)
.collect(Collectors.toList());
Integer retPict[] = new Integer[bwPict.size()];
return bwPict.toArray(retPict);
}
public static void main (String[] args)
{
Integer[] histo;
Integer img_y[] = new Integer[256];
// generate ramdom values just for testing algo
Random r = new Random();
for (int i=0;i< img_y.length; i++) {
img_y[i] = r.nextInt(MAX_VAL);
}
 
int[] histo = computeHistogram(img);
// ********* compute histogram ********************
 
histo = lumaHist(img_y,img_y.length);
int median = getMedian(width * height, histo);
 
System.out.println("histogram size =:" + histo.length );
BufferedImage bwimg = new BufferedImage(width, height, img.getType());
for (int sumy = 0; y < height; y++) {
for (int ix = 0; ix < histo.lengthwidth;i x++) {
Systembwimg.outsetRGB(x, y, luminance(img.printlngetRGB("histo["x, +y)) i>= +median "]? =:"0xFFFFFFFF +: histo[i]0xFF000000);
sum +=histo[i];
}
// check results are ok
// first check nb of elments in histo is 256
if (sum != img_y.length){
System.out.println("Error in histogram processing!\n"
+ "Numbers of value not coherent");
}
}
Integer hist[] = new Integer[16];
return Arrays.fill(hist, 0)bwimg;
}
for (int i=0;i< 256; i++) {
if (img_y[i] < 16) hist[0]++;
else if (img_y[i] < 32) hist[1]++;
else if (img_y[i] < 48) hist[2]++;
else if (img_y[i] < 64) hist[3]++;
else if (img_y[i] < 80) hist[4]++;
else if (img_y[i] < 96) hist[5]++;
else if (img_y[i] < 112) hist[6]++;
else if (img_y[i] < 128) hist[7]++;
else if (img_y[i] < 144) hist[8]++;
else if (img_y[i] < 160) hist[9]++;
else if (img_y[i] < 176) hist[10]++;
else if (img_y[i] < 192) hist[11]++;
else if (img_y[i] < 208) hist[12]++;
else if (img_y[i] < 224) hist[13]++;
else if (img_y[i] < 240) hist[14]++;
else hist[15]++;
 
private static int[] computeHistogram(BufferedImage img) {
int width = img.getWidth();
int height = img.getHeight();
 
int[] histo = new int[256];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
histo[luminance(img.getRGB(x, y))]++;
}
}
if (hist.length != histo.length) {
return histo;
System.out.println("Error in histogram processing!\n"
}
+ "histogram size is wrong ");
 
return;
private static int getMedian(int total, int[] histo) {
}
int median = else {0;
int sum = for (int i=0; i< histo.length;i++) {
for (int i = 0; i < histo.length && sum + if (!Objects.equals(histhisto[i], histo[< total / 2; i])++) {
sum += histo[i];
System.out.println("Error in histogram processing!\n"
median++;
+ "values are different (interv= " + i
}
+ " computed: " + histo[i]
return median;
+ " theorical :" + hist[i] + "\n");
}
return;
}</lang>
}
 
}
}
System.out.println("Test OK\n");
// ********* compute grayscale image ********************
Integer pictBW[];
pictBW = blackAndWhite(img_y,img_y.length);
for (int i=0;i< img_y.length; i++) {
System.out.println("Original[" + i +"]:" + img_y[i] +
" BandW[" + i +"]:" +pictBW[i] );
}
}
}
</lang>
=={{header|Julia}}==
<lang Julia>