Thursday, December 8, 2016

Software Engineering: Image Analysis with Java/JavaFx

Its been a little while since my last post, but I have been busy.
It is weird to travel through school and be tested. At every turn we feel like the work we are tasked with is nuisance. As we continue to push to meet our deadlines and develop projects to meet the expectations we learn why we love what we do. This is why computer science is so great. Every challenge instills a love and drive for something we never thought we would enjoy. All that being said, I have been working on a project for software engineering that I never thought I would enjoy. Image analysis. It has been roughly 3 weeks or so into my project development and it is almost like an addiction. blah blah blah, right. anyway, I'm here to show what has been made so far.

I have been working with javafx, fxml, jdbc, and eclipse. This hasn't been a picnic but has yielded a pretty nice project so far. The idea of this project is to take an image, and some data from that image, and use it to compare the likeliness of that image to another. My code, and project so far, is really rough and "dirty" as they say for a quick solutions, but I'm open to suggestions and help. Here are screen-shots of what I have so far.







The code is overloaded, dirty, and probably not very efficient but this is my learning curve as of late. I don't have much time to fix much before it is due. The database adapter is still in works but all the code can be found here:
 https://github.com/GettinDatFoShow/ImageAnalysis.git

For anyone who is interested in doing image comparison for their own projects.
Please don't shower me with comments of how ugly or incorrect the code is. I put it together in short time. My goal is to continue to improve it over time and to work with others who have questions about how they would like to do image comparison.

The percentages in the program have been decided in this way:
I decided to first separate the rgb vales and count up a total for each, then divide them by the total that they could be per the pixel count. ie. add up all red values then divide by 255*how many pixels there were.
for colorfulness, I defined it as: the total unique values of each three valued pixel, ie. 255-255-255 then divided the total by the amount of pixels in the image as a total prospect for different values that could occur.  I realized that the colorfulness of a photo is purely defined by the person designing the program and after tough consideration, this is where I arrived. I WOULD LOVE someone else's opinion on how to present this detail. Anyway, this is here because I love to code and I love creativity. So, I would love to hear your
opinions. Thanks, and code on.

Here is the absolutely awful and badly mad image compare image class otherwise known as ICImage.java


remember, this does not include the javaFX controller, or fxml or main class which can all be found in the git hub link. enjoy. (ps, i wish i could have commented more but if you have questions, please ask.)

package application;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class ICImage extends Component {
public final int A = 24;
public final int R = 16;
public final int G = 8;
public int iWidth;
public int iHeight;
public int pixelTotal;
public int[] iPArray;
public int[] iRArray;
public int[] iGArray;
public int[] iBArray;
public int[] iAArray;
public int[][] iColorPixelArray;
public int[][][] iColorIntArray;
public ArrayList<String> totalColors = new ArrayList<String>();
public int iAbin[];
public int iRbin[];
public int iGbin[];
public int iBbin[];
public String IURL;
public String iDate;
public String iName;
public String iSrc;
public BufferedImage image;
public Color color;
public File imageFile;
public double[] percentages = new double[4];
public double totalColor;
public double transparentcy;
public double percentRed;
public double percentGreen;
public double percentBlue;
public double colorFulness;
public double totalColorPercentage;
// constructor begin
public ICImage(File file)
{
this.imageFile = file;
try {
this.image = ImageIO.read(file);
} catch (IOException e) {
System.out.println("ERROR: NO IMAGE!!");
System.out.print("FILE PATH : ");
System.out.print(this.imageFile.getAbsolutePath());
e.printStackTrace();
}
this.setIURL(file);
this.setISource(this.imageFile.getAbsolutePath());
this.setINameFromFile(file);
this.setIHeight(image);
this.setIWidth(image);
this.setColorArrays(image);
this.findTotalColors();
this.setIcolorPercentages();
this.setIDate();
}
public ICImage(String imageSource)
{
this.setISource(imageSource); // link to image
this.createBImage(); // create buffered image
this.setIDate();
this.findTotalColors();
this.setIcolorPercentages();
}
public ICImage(String imageSource, String imageName)
{
this.setISource(imageSource); // link to image
this.createBImage(); // create buffered image
this.setIName(imageName);
this.setIDate();
this.findTotalColors();
this.setIcolorPercentages();
}
// constructor end
// MUTATORS ====== ( SET METHODS ) ======
public void setIURL(File file)
{
try {
this.IURL = file.toURI().toURL().toString();
} catch (MalformedURLException e) {
System.out.println("MalformedURL Exception");
e.printStackTrace();
}
}
public void setINameFromFile(File file)
{
this.iName = file.getName();
int pos = this.iName.lastIndexOf(".");
if (pos > 0) {
this.iName = this.iName.substring(0, pos);
}
}
public void setISource(String imageSource){ // setting image source (iSrc) with string
this.iSrc = imageSource;
}
public void createBImage()
{ // method creates buffered image object
String imageSource = this.getISource();
try{
this.image = ImageIO.read(this.getClass().getResource(imageSource)); // set up buffered image
}catch(IOException e){
System.err.println(e.getMessage());
}
this.setIHeight(image);
this.setIWidth(image);
this.setColorArrays(image);
this.setIDate();
}
public void createBImage(String imageLocation)
{ // overload method creates buffered image object
try{
this.image = ImageIO.read(this.getClass().getResource(imageLocation)); // set up buffered image
}catch(IOException e){
System.err.println(e.getMessage());
}
this.setIHeight(image);
this.setIWidth(image);
this.setColorArrays(image);
this.setIDate();
}
public void setIHeight(BufferedImage image)
{ // setting iHeight
this.iHeight = image.getHeight();
}
public void setIWidth(BufferedImage image)
{ // setting iWidth
this.iWidth = image.getWidth();
}
public void setColorArrays(BufferedImage image)
{ // setting ColorArray
int h = this.getIHeight();
int w = this.getIWidth();
int pixel;
this.iColorPixelArray = new int[h][w];
int[] alphaArray = new int[h*w];
int[] redArray = new int[h*w];
int[] greenArray = new int[h*w];
int[] blueArray = new int[h*w];
int counter = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
pixel = image.getRGB(j, i);
alphaArray[counter] = this.getAlpha(pixel);
redArray[counter] = this.getRed(pixel);
greenArray[counter] = this.getGreen(pixel);
blueArray[counter] = this.getBlue(pixel);
this.iColorPixelArray[i][j] = pixel;
counter += 1;
}
}
setPixelTotal(counter);
setIAArray(alphaArray);
setIRArray(redArray);
setIGArray(greenArray);
setIBArray(blueArray);
setBins(alphaArray, redArray, greenArray, blueArray);
}
public void setIName(String imageName){
this.iName = imageName;
}
public void setIAArray(int[] alphaArray){
this.iAArray = alphaArray;
}
public void setIBArray(int[] blueArray){
this.iBArray = blueArray;
}
public void setIRArray(int[] redArray){
this.iRArray = redArray;
}
public void setIGArray(int[] greenArray){
this.iGArray = greenArray;
}
public void setBins(int[] alphaArray, int[] redArray, int[] greenArray, int[] blueArray){
this.iAbin = new int[256];
this.iRbin = new int[256];
this.iGbin = new int[256];
this.iBbin = new int[256];
for(int i = 0; i < 256; i++){
this.iAbin[i]=0;
this.iRbin[i]=0;
this.iGbin[i]=0;
this.iBbin[i]=0;
}
int end = alphaArray.length;
for(int i = 0; i < end ; i++){
this.iAbin[alphaArray[i]] += 1 ;
this.iRbin[redArray[i]] += 1;
this.iGbin[greenArray[i]] += 1;
this.iBbin[blueArray[i]] += 1 ;
}
}
public void findTotalColors(){
int end = this.getPixelTotal();
String red= "";
String green="";
String blue="";
ArrayList<String> result = new ArrayList<String>();
int total;
for(int i = 0; i < end; i++){
red= "";
green="";
blue="";
red = Integer.toString(this.iRArray[i]);
green = Integer.toString(this.iGArray[i]);
blue = Integer.toString(this.iBArray[i]);
result.add(red+green+blue);
}
Collections.sort(result);;
int pointer = 0;
this.totalColors.add(result.get(0));
for(int i = 0; i < end; i++){
if(result.get(i).equals(this.totalColors.get(pointer))){
}
else{
this.totalColors.add(result.get(i));
pointer +=1;
}
}
}
public void setIcolorPercentages(){
double red = 0;
double alpha = 0;
double blue = 0;
double green = 0;
double end = this.iRArray.length;
long total = this.iRArray.length*255;
this.totalColor = 0;
for(int i = 0; i < end; i++){
alpha += this.iAArray[i];
red += this.iRArray[i];
blue += this.iBArray[i];
green += this.iGArray[i];
this.totalColor = red + blue + green;
}
// System.out.println(alpha);
// System.out.println(red);
// System.out.println(green);
// System.out.println(blue);
// System.out.println(total);
// System.out.println("**************");
this.transparentcy = alpha/totalColor*100;
this.percentRed = red/totalColor*100;
this.percentGreen = green/totalColor*100;
this.percentBlue = blue/totalColor*100;
System.out.println(this.getPixelTotal());
System.out.println(this.totalColors.size());
this.colorFulness = (double) this.totalColors.size() / (double) this.getPixelTotal()*100;
System.out.println(this.transparentcy);
System.out.println(this.percentRed);
System.out.println(this.percentGreen);
System.out.println(this.percentBlue);
System.out.print("colorfulness: ");
System.out.println(this.colorFulness);
this.percentages[0] = this.transparentcy;
this.percentages[1] = this.percentRed;
this.percentages[2] = this.percentGreen;
this.percentages[3] = this.percentBlue;
}
public void setIDate(){
//getting current date and time using Date class
DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Date dateobj = new Date();
this.iDate = df.format(dateobj);
}
public void setPixelTotal(int counter){
this.pixelTotal = counter;
}
// ACCESSORS ====== ( GET METHODS ) ======
public String getIURL(){
return this.IURL;
}
public String getISource(){ // getting image source (iSrc) string
return this.iSrc;
}
public String getIName(){
return this.iName;
}
public BufferedImage getICImage(){
return this.image;
}
public int getIHeight(){
return this.iHeight;
}
public int getIWidth(){
return this.iWidth;
}
public int[][] getIColorPixelArray(){
return this.iColorPixelArray;
}
public int[] getIAArray(){
return this.iAArray;
}
public int[] getIBArray(){
return this.iBArray;
}
public int[] getIRArray(){
return this.iRArray;
}
public int[] getIGArray(){
return this.iGArray;
}
public int getAlpha(int pixel){
return (pixel >> this.A) & 0xff;
}
public int getRed(int pixel){
return (pixel >> this.R) & 0xff;
}
public int getGreen(int pixel){
return (pixel >> this.G) & 0xff;
}
public int getBlue(int pixel){
return (pixel) & 0xff;
}
public String getIDate(){
return this.iDate;
}
public int getPixelTotal(){
return this.pixelTotal;
}
// ===== ( OVERLOADED GET FUNCTIONS ) ======
public double getAlpha(int[][] colorArray, int x, int y){
int pixel = colorArray[y][x];
return getAlpha(pixel);
}
public double getRed(int[][] colorArray, int x, int y){
int pixel = colorArray[y][x];
return getRed(pixel);
}
public double getGreen(int[][] colorArray, int x, int y){
int pixel = colorArray[y][x];
return getGreen(pixel);
}
public double getBlue(int[][] colorArray, int x, int y){
int pixel = colorArray[y][x];
return getBlue(pixel);
}
public int[] getAlphaBin(){
return this.iAbin;
}
public int[] getRedBin(){
return this.iRbin;
}
public int[] getGreenBin(){
return this.iGbin;
}
public int[] getBlueBin(){
return this.iBbin;
}
// public double[] getIcolorPercentages(){
//// this.setIcolorPercentages();
// return this.IcolorPercentages;
// }
} // ************************ end of ICImage Class *****************************

Tuesday, October 25, 2016

Test How your Computer Handles Various Java Sorting Algorithms

Would  you like to test your computer and see how it handles sorting?
Here is a simple Java program that will allow you to run a few different sorting algorithms side by side and compare their speed in milliseconds.
Included algorithms are:
  • Bubble Sort
  • Selection Sort 
  • Insertion Sort
  • Merge Sort
  • Quick Sort
I realize there are many more and the code is pretty simple to follow and understand so feel free to download and manipulate it as you please. Enjoy! #SudoAptGetUpdateYourBrain

you can find the .zip to the code here:
https://drive.google.com/file/d/0B9JH6EHjkfuRVXZoaEotdWJzZXM/view?usp=sharing

or copy the following and enter them into your own program.
the code is separated into three files seperated by package sorttestdemo header. the ReadMe.doc
is only included in the .zip file along with a image of the code running on my machine.




/*
* This program (SortTestDemo.java & RandomList.java) was created and writen by Robert Morris on 10/21/2016
* SortList.java was created by Robert Morris with sorting algorithms from:
* https://thilinasameera.wordpress.com/2011/06/01/sorting-algorithms-sample-codes-on-java-c-and-matlab/
* @author Robert Morris
*/
package sorttestdemo;

/**
*
* @author Robert Morris
*/
public class SortTestDemo {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
int listSize = 100000; // Initial Starting length of random array to be sorted:
// (WARNING! WILL INCREASE BY A MULTIPLE OF 5, 5 times.)

RandomList randomizedList = new RandomList(); // initialize RandomList Obejct to be operated on.
randomizedList.setListSize(listSize);
randomizedList.randomizeList();
long startTime;
long endTime;
long totalTime;
// copy of list are changed to prevent the usuage of the same array after it has been mutated.
// this could probably be avoided by using a deep copy. But in this case, a simple helper methode worked.
int[] bubbleList = createListCopy(randomizedList.getList());
int[] selectionList = createListCopy(randomizedList.getList());
int[] insertionList = createListCopy(randomizedList.getList());
int[] mergeList = createListCopy(randomizedList.getList());
int[] quickList = createListCopy(randomizedList.getList());
String[] algoNames = {"BubbleSort", "SelectionSort", "InsertionSort", "MergeSort", "QuickSort"};

SortList s = new SortList(); // initialize class of sort methods
// for (int i = 1; i <= 5; i++){
displayLength(listSize);

//randomizedList.displayUnsortedList(); // check to see if list is really randomized

startTime = System.currentTimeMillis();
bubbleList = s.bubbleSort(bubbleList); // Test number 1 (BubbleSort)
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
displayTime(algoNames[0], totalTime); // output time display
//displayList(finalizedList); // check to see if list is really sorted

startTime = System.currentTimeMillis();
selectionList = s.selectionSort(selectionList); // Test number 2 (SelectionSort)
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
displayTime(algoNames[1], totalTime); // output time display
//displayList(finalizedList); // check to see if list is really sorted

startTime = System.currentTimeMillis();
insertionList = s.insertionSort(insertionList); // test number 3 (Insertion Sort)
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
displayTime(algoNames[2], totalTime);different color coated files // output time display
//displayList(finalizedList); // check to see if list is really sorted

startTime = System.currentTimeMillis();
mergeList = s.mergeSort(mergeList); // test number 4 (MergeSort)
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
displayTime(algoNames[3], totalTime); // output time display
//displayList(finalizedList); // check to see if list is really sorted

startTime = System.currentTimeMillis();
quickList = s.quickSort(quickList); // test number 5 (QuickSort)
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
displayTime(algoNames[4], totalTime); // output time display
//displayList(finalizedList); // check to see if list is really sorted

// listSize *= 5; // increase the size of the list by a multiple of 5
// }
}

public static void displayList(int[] theList){
for(int i=0; i<theList.length; i++){
System.out.println(theList[i]);
}
}

public static void displayTime(String algos, long time){
System.out.print("Sort Time of *"+ algos +"* = ");
System.out.print(time);
System.out.println(" Milliseconds. ");
}

public static void displayLength(int listSize){
System.out.println();
System.out.print("Sort Times for a List of Size ---> ");
System.out.print(listSize);
System.out.println(": ");
}
public static int[] createListCopy(int[] oldList){
int[] newList = new int[oldList.length];
for(int i = 0; i < oldList.length; i++ ){
newList[i] = oldList[i];
}
return newList;
}

}


package sorttestdemo;

/**
*
* @author Robert Morris
* This class provides a list of sorting methods that sort arrays
* of integers in accending order.
* The list of sorting methods include:
* BubbleSort, SelectionSort, InsertionSort, MergeSort, QuickSort
*/
public class SortList {
// CONSTRUCTOR
public SortList(){
}
// BUBBLESORT !!!
public int[] bubbleSort(int[] data){
int lenD = data.length;
int tmp = 0;
for(int i = 0;i<lenD;i++){
for(int j = (lenD-1);j>=(i+1);j--){
if(data[j]<data[j-1]){
tmp = data[j];
data[j]=data[j-1];
data[j-1]=tmp;
}
}
}
return data;
}
// SELECTION SORT !!!
public int[] selectionSort(int[] data){
int lenD = data.length;
int j = 0;
int tmp = 0;
for(int i=0;i<lenD;i++){
j = i;
for(int k = i;k<lenD;k++){
if(data[j]>data[k]){
j = k;
}
}
tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
return data;
}
// INSERTIONSORT !!!
public int[] insertionSort(int[] data){
int len = data.length;
int key = 0;
int i = 0;
for(int j = 1;j<len;j++){
key = data[j];
i = j-1;
while(i>=0 && data[i]>key){
data[i+1] = data[i];
i = i-1;
data[i+1]=key;
}
}
return data;
}
// MERGE SORT !!!

public int[] mergeSort(int[] data){
int lenD = data.length;
if(lenD<=1){
return data;
}
else{
int[] sorted = new int[lenD];
int middle = lenD/2;
int rem = lenD-middle;
int[] L = new int[middle];
int[] R = new int[rem];
System.arraycopy(data, 0, L, 0, middle);
System.arraycopy(data, middle, R, 0, rem);
L = this.mergeSort(L);
R = this.mergeSort(R);
sorted = merge(L, R);
return sorted;
}
}
public int[] merge(int[] L, int[] R){
int lenL = L.length;
int lenR = R.length;
int[] merged = new int[lenL+lenR];
int i = 0;
int j = 0;
while(i<lenL||j<lenR){
if(i<lenL & j<lenR){
if(L[i]<=R[j]){
merged[i+j] = L[i];
i++;
}
else{
merged[i+j] = R[j];
j++;
}
}
else if(i<lenL){
merged[i+j] = L[i];
i++;
}
else if(j<lenR){
merged[i+j] = R[j];
j++;
}
}
return merged;
}

// QUICKSORT !!!
public int[] quickSort(int[] data){
int lenD = data.length;
int pivot = 0;
int ind = lenD/2;
int i,j = 0,k = 0;
if(lenD<2){
return data;
}
else{
int[] L = new int[lenD];
int[] R = new int[lenD];
int[] sorted = new int[lenD];
pivot = data[ind];
for(i=0;i<lenD;i++){
if(i!=ind){
if(data[i]<pivot){
L[j] = data[i];
j++;
}
else{
R[k] = data[i];
k++;
}
}
}
int[] sortedL = new int[j];
int[] sortedR = new int[k];
System.arraycopy(L, 0, sortedL, 0, j);
System.arraycopy(R, 0, sortedR, 0, k);
sortedL = quickSort(sortedL);
sortedR = quickSort(sortedR);
System.arraycopy(sortedL, 0, sorted, 0, j);
sorted[j] = pivot;
System.arraycopy(sortedR, 0, sorted, j+1, k);
return sorted;
}
}
}


/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package sorttestdemo;
import java.util.Random;
/**
* This class creates and provides methods for manipulating a random array
* of integers.
* @author Robert Morris
*/
public class RandomList {
public int listSize;
public int[] unsortedList;

public RandomList(){}
public RandomList(int listSize){
setListSize(listSize);
randomizeList();
}
public int[] getList(){
return this.unsortedList;
}
public void setListSize(int newSize){
this.listSize = newSize;
}
public void randomizeList(){
Random r = new Random();
this.unsortedList = new int[this.listSize];
for(int i = 0; i < this.listSize; i++){
this.unsortedList[i] = r.nextInt(1000);
}
}
public void displayUnsortedList(){
for(int j=0; j< this.listSize; j++ ){
System.out.println(this.unsortedList[j]);
}
}

}