week 4 ++ more image process

contrast stretching (code) : the idea is to find the lower and upper gray bound for an image and then stretch them to white and black. I actually did this in three steps, though I probably could have condensed it down.
1 - make histogram of original image
2 - make histogram only of the range of the original
3 - now stretch it out into a new full-sized histogram
though the actual drawn final image doesn't require this 3-step process, and actually I had some trouble getting the lower gray bound to work.

/* from the update() */				
				
float pctX = (float)mouseX / (float)ofGetWidth();
float pctY = (float)mouseY / (float)ofGetHeight();

for (int i = 0; i < texW; i++){
	for (int j = 0; j < texH; j++){
		
		// -- 2-image multiplying (variable) --
		int t_var = int(pctY*(num_img - 2));
		float per_multi = float(Pixels[t_var][j * texW + i])/255.0f;
		TexPixels[0][j * texW + i] = (unsigned char)(MIN(255*pctX,
					Pixels[t_var + 1][j * texW + i] * per_multi));
	}
}
for(int t = 0; t < 2; t++){
	// get the pixels into the texture
	Textures[t].loadData(TexPixels[t], texW,texH, GL_LUMINANCE); 
}


// -- HISTOGRAMS :: CALCULATE -- 

for(int h = 0; h < 255; h++){
	Histogram0[h] = 0;
	Histogram1[h] = 0;
}
hist_max0 = 0;
hist_max1 = 0;
hist_maxX = 0;
hist_lobound = 0; 
hist_hibound = 255;

for (int i = 0; i < texW; i++){
	for (int j = 0; j < texH; j++){
		for(int h = 0; h < 255; h++){
		
			// -- plot histogram of original
			if(TexPixels[0][j * texW + i] == h){
				Histogram0[h]++;
			}
			hist_max0 = MAX(hist_max0, Histogram0[h]);
		}
	}
}

for(int h = 0; h < 255; h++){
	// -- calculate bounds / range of original histogram
	if(Histogram0[h] == 0){
		//hist_lobound = MAX(hist_lobound, h);		// <-- this needs work
		hist_hibound = MIN(hist_hibound, h);
	}
	hist_range = hist_hibound - hist_lobound;
}

// -- temporary histogram space
for(int h = 0; h < hist_range; h++){
	HistogramX[h] = Histogram0[h + hist_lobound];
	hist_maxX = MAX(hist_maxX, HistogramX[h]);
}	
	
// -- 
for(int h = 0; h < 255; h++){
	Histogram1[h] = HistogramX[int(floor(h * hist_range / 255))];
	hist_max1 = MAX(hist_max1, Histogram1[h]);
}
	
// -- write stretched image
for (int p = 0; p < texW * texH; p++){
	TexPixels[1][p] = (TexPixels[0][p] - hist_lobound)*(255 / hist_range);
}

				

histograms of blended images (code) : two different histograms of two blended images from the last assignment

/* in the update() */				
				
float pctX = (float)mouseX / (float)ofGetWidth();
float pctY = (float)mouseY / (float)ofGetHeight();

for (int i = 0; i < texW; i++){
	for (int j = 0; j < texH; j++){
		for (int k=0; k < num_img; k++){
			
			// -- contrasting (variable) --
			if (Pixels[k][j * texW + i] > 127){
				TexPixels[1][j * texW + i] = MIN(255, 
						TexPixels[1][j * texW + i] + (inv_img) * Pixels[k][j * texW + i] + 255*pctX);
			}else{
				TexPixels[1][j * texW + i] = MAX(0, 
						TexPixels[1][j * texW + i] - (inv_img) * Pixels[k][j * texW + i] - 255*pctY);
			}
				
			// -- contrasting + thresholding (variable) --
			if (Pixels[k][j * texW + i] > int(255*pctY)){
				TexPixels[2][j * texW + i] = MIN(255, 
						TexPixels[2][j * texW + i] + (inv_img) * Pixels[k][j * texW + i] + 255*pctX);
			}else{
				TexPixels[2][j * texW + i] = MAX(0, 
						TexPixels[2][j * texW + i] - (inv_img) * Pixels[k][j * texW + i] - 255*pctX);
			}	
				
		}
					
	}
}
for(int t = 1; t < 3; t++){
	// get the pixels into the texture
	Textures[t].loadData(TexPixels[t], texW,texH, GL_LUMINANCE); 
}


// -- HISTOGRAMS :: CALCULATE -- 

for(int h = 0; h < 255; h++){
	Histogram0[h] = Histogram1[h] = Histogram2[h] = Histogram3[h] = 0;
}
hist_max0 = hist_max1 = hist_max2 = hist_max3 = 0;
for (int i = 0; i < texW; i++){
	for (int j = 0; j < texH; j++){
		for(int h = 0; h < 255; h++){
			/*if(TexPixels[0][j * texW + i] == h){;
				Histogram0[h]++;
			}
			hist_max0 = MAX(hist_max0, Histogram0[h]);
			*/
			if(TexPixels[1][j * texW + i] == h){;
				Histogram1[h]++;
			}
			hist_max1 = MAX(hist_max1, Histogram1[h]);
			
			if(TexPixels[2][j * texW + i] == h){;
				Histogram2[h]++;
			}
			hist_max2 = MAX(hist_max2, Histogram2[h]);
			
		}
	}
}


				


directions... NSEW (code) : getting pixels to change based on neighboring pixel criteria (dilation, erosion, and I threw in edge detection). not bad, although the effect is pretty subtle and the screens don't really do it justice, so you can open them in a new window to see a little more detail but even then it's almost a neglible effect, which means that we'll have to think of dynamically expanding the neighboring pixel range, some radius.
- erosion

- dilation

- edge detection


/* in the update() */

// -- variable thresholding
int pctX = 255*mouseX/1500;
for (int i = 0; i < imageW*imageH; i++){
	if(pixelsA[i] > pctX){
		pixelsB[i] = 255;
	}
	if(pixelsA[i] <= pctX){
		pixelsB[i] = 0;
	}
}

// -- erosion -- black, black, black
/*
unsigned char test_me = 255;
unsigned char test_nbor = 255;
unsigned char test_true = 255;
unsigned char test_false = 0;
*/

// -- dilation -- black, white, white
/*
unsigned char test_me = 0;
unsigned char test_nbor = 0;
unsigned char test_true = 0;
unsigned char test_false = 255;
*/

// -- edge detection -- black, white, black

unsigned char test_me = 0;
unsigned char test_nbor = 255;
unsigned char test_true = 255;
unsigned char test_false = 0;


// -- pixel testing NSEW
for (int i = 1; i < imageW - 1; i++){
	for (int j = 1; j < imageH - 1; j++){
		
		int nw = (j - 1) * imageW + i - 1;
		int w  = (j - 0) * imageW + i - 1;
		int sw = (j + 1) * imageW + i - 1;
		int n  = (j - 1) * imageW + i - 0;
		int me = (j    ) * imageW + i    ;
		int s  = (j - 1) * imageW + i - 0;
		int ne = (j - 1) * imageW + i + 1;
		int e  = (j - 0) * imageW + i + 1;
		int se = (j + 1) * imageW + i + 1;
		
		pixelsC[me] = pixelsB[me];
		
		if(pixelsB[me] == test_me){
			if( pixelsB[nw] == test_nbor ||
				pixelsB[w]  == test_nbor ||
				pixelsB[sw] == test_nbor ||
				pixelsB[n]  == test_nbor ||
				pixelsB[s]  == test_nbor ||
				pixelsB[ne] == test_nbor ||
				pixelsB[e]  == test_nbor ||
				pixelsB[se] == test_nbor
			){
				pixelsC[me] = test_true;
			}
			else{
				pixelsC[me] = test_false;
			}
		}
		else{
			pixelsC[me] = test_false;
		}	
	}
}