How can I detect a specific 3d model collision three.js - javascript

I am trying to make clickable 3d objects with Leap Motion. I have two 3D models, IronMan helmet and a Hammer of Thor. If one of those two object is selected, then will change color. For the Iron Man will be green and for the Hammer will be white. But when I am selecting the Hammer, it changes to green instead of white. I use a cube as a pointer to select the object. Can you help?
This is the code to insert 3d models:
var colladaMeshlist = [];
model = new THREE.Object3D()
var object;
var skin;
var objectScale = 1.5;
rotX=0, rotY=0, rotZ=0;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( 'models/IronMan.dae', function (collada) {
object = collada.scene;
object.scale.x = object.scale.y = object.scale.z = objectScale;
object.position.x= 20;
object.position.y= -40;
object.position.z= 0;
object.rotation.x= rotX;
object.rotation.y= rotY;
object.rotation.z= rotZ;
object.name="IronMan";
colladaMeshlist.push(object);
model.add(object);
});
scene.add(model);
model2 = new THREE.Object3D()
var object2;
var skin2;
var objectScale2 = 1;
posX=0, posY=-40, posZ=0;
rotX=0, rotY=0, rotZ=0;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( 'models/Hammer.dae', function (collada) {
object2 = collada.scene;
object2.scale.x = object2.scale.y = object2.scale.z = objectScale2;
object2.position.x= -20;
object2.position.y= -20;
object2.position.z= posZ;
object2.rotation.x= rotX;
object2.rotation.y= rotY;
object2.rotation.z= rotZ;
object2.name="Hammer";
colladaMeshlist.push(object2);
model2.add(object2);
});
scene.add(model2);
This is the code for selecting the objects:
var originPoint = cube.position.clone();
for(var vertexIndex = 0; vertexIndex < cube.geometry.vertices.length; vertexIndex++)
{
var localVertex = cube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( cube.matrix );
var directionVector = globalVertex.sub( cube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects(colladaMeshlist, true);
if(collisionResults.length > 0 && collisionResults[0].distance < directionVector.length())
{
collisionResults[0].object.material.color.setHex(0x4CAF50);
}
else if (collisionResults.length > 0 && collisionResults[1].distance < directionVector.length())
{
collisionResults[1].object.material.color.setHex(0xffffff);
}
}

Related

How to Identify Clipping Mask using javascript without ratios for photoshop?

I want to find all clipping mask layer from psd. but problem is how can we identify clipping mask layers in psd currently I'm using below code.
I tried this How to identify clipping masks in Photoshop using JavaScript
But it is not working.
for (var x = 0; x < layers.length; x++) {
var layerindex = layers[x];
doc.activeLayer = doc.artLayers[x];
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if(desc.hasKey(charIDToTypeID('GrpL'))){
alert("this is Clipping Mask Layer");
}
}
var doc = activeDocument,
layers = activeDocument.layers;
for (var x = 0; x < layers.length; x++)
{
doc.activeLayer = doc.layers[x];
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (desc.hasKey(charIDToTypeID('Grup')) && desc.getBoolean(charIDToTypeID('Grup')))
{
alert("this is Clipping Mask Layer: " + doc.activeLayer.name);
}
}

Adding duplicate tiles from different arrays PIXI.js

I'm trying to create a slot game;
I have some images that I put into an array
var createSlots = function(){
//setup images as tilingSprites
var slot1 = new PIXI.extras.TilingSprite(t1, 200, 200);
var slot2 = new PIXI.extras.TilingSprite(t2, 200, 200);
var slot3 = new PIXI.extras.TilingSprite(t3, 200, 200);
var slot4 = new PIXI.extras.TilingSprite(t4, 200, 200);
var slot5 = new PIXI.extras.TilingSprite(t5, 200, 200);
var slot6 = new PIXI.extras.TilingSprite(t6, 200, 200);
var slot7 = new PIXI.extras.TilingSprite(t7, 200, 200);
var slot8 = new PIXI.extras.TilingSprite(t8, 200, 200);
var slot9 = new PIXI.extras.TilingSprite(t9, 200, 200);
var slot10 = new PIXI.extras.TilingSprite(t10, 200, 200);
//push slots into array; images, sprites etc.
mainSlotArr.push(slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8, slot9, slot10);
};
for the moment I have 2 functions (will combine them once I get this working)
createReels1 and createReels2
what they do is copy the mainSlotArray use a shuffle function
Then populate to 2 columns (reels) each (at the moment createReels2 only does one reel)
it then removes the array element from the array it's using
The trouble I'm having is that whatever image tiles are used in createReels2, disappear if they are being used in createReels1 function, e.g if image1.png used in createReels2 and createReels1, then it is not visible in the first 2 reels
createReels functions below (alot of hard coding!)
var createReels1 = function(){
slotArr1 = mainSlotArr.slice();
shuffle(slotArr1);
var counter = 0;
var num = 0
for(var i = 0; i <2; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = i*130;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr1[j];
var toDel = slotArr1.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
console.log(slot);
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[i].addChild(slot);
slotArr1.splice(toDel, 1);//remove from array
}
}
}
var createReels2 = function(){
slotArr2 = mainSlotArr.slice();
shuffle(slotArr2);
var counter = 0;
var num = 0
for(var i = 0; i <1; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = 260;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr2[j];
var toDel = slotArr2.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[2].addChild(slot);
slotArr2.splice(toDel, 1);//remove from array
}
}
}
If I understood the code correctly, with quick check:
Sprites can have only one parent. If you check the Sprite object, it actually has a parent property. So slotArr1 and slotArr2 have identical Sprites and that fact doesn't change id you slice them. Then when you are assigning them to different containers, they get moved from one container to the other. You can reuse textures sure, but one Sprite can only have on parent.

Easeljs game project

I'm working on a game project but I have a a problem i received this error:
NS_ERROR_NOT_AVAILABLE:
ctx.drawImage(this.image, 0, 0); //Bitmap.js in Easeljs lib.
I used the bitmap in the next codes. Please tell me if in this there is a problem and how to fix it.
Thanks for collaboration.
Code 1:
p.initialize = function(x,y ,stage, world){
var bmp = new Bitmap('../assets/blackBall.png');
//console.log(bmp)
//alert(bmp)
bmp.regX = radius;
bmp.regY = radius;
bmp.x=x;
bmp.y=y;
this.skin = bmp;
stage.addChild(bmp);
var fixDef = new b2FixtureDef();
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.8;
fixDef.shape = new b2CircleShape(38*CONST.pixelToMeter);
var bodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.x = bmp.x*CONST.pixelToMeter;
bodyDef.position.y = bmp.y*CONST.pixelToMeter;
this.body = world.CreateBody(bodyDef);
this.body.CreateFixture(fixDef);
this.skin.body = this.body;
setUserData(this.body);
/*Event handler*/
this.skin.onMouseOver = handleMouseOver;
this.skin.onMouseOut = handleMouseOut;
this.skin.onPress = handleMouseDown;
//console.log(this.skin);
}
Code 2:
p.initialize = function(stage, world){
var shooterSkin = new Container();
var cirlceSkin = new createjs.Bitmap('../assets/shooter.png');
cirlceSkin.name = "ball";
var arrowSkin = new createjs.Bitmap('../assets/arrow.png');
arrowSkin.name = "arrow";
arrowSkin.rotation = 0;
arrowSkin.scaleX =0;
arrowSkin.regY = arrowHeight;
cirlceSkin.regX = skinRadius;
cirlceSkin.regY = skinRadius;
cirlceSkin.x =0;
cirlceSkin.y = 0;
cirlceSkin.alpha=circleAlpha;
shooterSkin.x=110
shooterSkin.y = 110;
shooterSkin.addChild(cirlceSkin);
shooterSkin.addChild(arrowSkin);
arrowIndex = 1;
this.skin = shooterSkin;
stage.addChild(shooterSkin);
var fixDef = new b2FixtureDef();
fixDef.friction = 0;
fixDef.restitution = 0;
fixDef.isSensor = true;
fixDef.shape = new b2CircleShape(radius*CONST.pixelToMeter);
var bodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_kineticBody;
bodyDef.position.x = shooterSkin.x*CONST.pixelToMeter;
bodyDef.position.y = shooterSkin.y*CONST.pixelToMeter;
this.body = world.CreateBody(bodyDef);
this.body.CreateFixture(fixDef);
setUserData(this.body);

How can I access imageData from a renderTarget?

I'm a university masters degree student in Computer Graphics, I'm having difficulty using three.js to access the image data(pixels) of a texture created with a EffectComposer.
The first composer (composer) is using a line detection shader to find road lines in a lane, and put the result in a renderTarget (rt_Binary). My second composer (fcomposer2) uses a shader that paints an area green if is within a certain space.
The plan was to render the composer first and after analysing the rt_Binary image i could determine the limits.
I found some functions that allow me to get the imagedata (getImageData(image) and getPixel(imagedata, x, y)) but they only work on these occasions:
// before image
var imagedata = getImageData(videoTexture.image);
// processed image
var imagedata2 = getImageData(renderer.domElement);
If a put the first composer to render to screen, i get the correct values for the limits, but when i put the second composer, i get the wrong values for the limits.
Is there any way to get the imageData from a renderTarget? is so, how?
Edit1:
Here's the code for script that i use for the html:
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>Tests WebGL</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="three.js/build/three.js"></script>
<script src="js/CopyShader.js"></script>
<script src="js/EffectComposer.js"></script>
<script src="js/MaskPass.js" ></script>
<script src="js/RenderPass.js" ></script>
<script src="js/ShaderPass.js"></script>
<script src="js/stats.min.js" ></script>
<!-- Shaders -->
<script src="js/shaders/KernelShader.js" ></script>
<script src="js/shaders/SimpleShader.js"></script>
<script src="js/shaders/MyShader.js"></script>
<script src="js/shaders/BinaryShader.js"></script>
<script type="text/javascript">
var scene, fscene, sceneF;
var camera;
var renderer, rt_Binary;
var composer;
var stats;
var fmaterial;
var videoTexture;
var videoWidth = 480;
var videoHeight = 270;
var rendererWidth = videoWidth;
var rendererHeight = videoHeight;
var x_max = 345;//videoWidth*0.72; //
var x_min = 120;//videoWidth*0.25; //
var y_max = 189;//videoHeight*0.7 ;
var y_min = 148;//videoHeight*0.55;
// var ml=0.0, mr=0.0, mm=0.0;
// var bl=0.0, br=0.0, bm=0.0;
var yMaxL = 0, yMinL = 0, yMaxR = 0, yMinR = 0;
var xMaxL = 0, xMinL = 0, xMaxR = 0, xMinR = 0;
var frame = 0;
// init the scene
window.onload = function() {
renderer = new THREE.WebGLRenderer(
{
antialias: true, // to get smoother output
preserveDrawingBuffer: true // to allow screenshot
});
renderer.setClearColor(0xffffff, 1);
renderer.autoClear = false;
renderer.setSize(rendererWidth, rendererHeight);
document.getElementById('container').appendChild(renderer.domElement);
//add stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(stats.domElement);
// create Main scene
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(35, rendererWidth / rendererHeight, 1, 10000);
camera.position.set(0, 1, 6);
scene.add(camera);
// define video element
video = document.createElement('video');
// video.src = 'GOPR0007.webm';
video.src = 'output.webm';
video.width = videoWidth;
video.height = videoHeight;
video.autoplay = true;
video.loop = true;
//create 3d object and apply video texture to it
var videoMesh = new THREE.Object3D();
scene.add(videoMesh);
videoTexture = new THREE.Texture(video);
var geom = new THREE.PlaneGeometry(1, 1);
material = new THREE.MeshBasicMaterial({map: videoTexture});
var mesh = new THREE.Mesh(geom, material);
videoMesh.add(mesh);
var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBufer: false };
rt_Binary = new THREE.WebGLRenderTarget( videoWidth, videoHeight, renderTargetParameters );
// Composers
// composer = new THREE.EffectComposer(renderer, renderTarget2);
composer = new THREE.EffectComposer(renderer, rt_Binary );
composer.addPass(new THREE.RenderPass(scene, camera));
var simple = new SimpleShader.Class(videoWidth, videoHeight);
var simEffect = new THREE.ShaderPass(simple.shader);
composer.addPass(simEffect);
var ef = new BinaryShader.Class(videoWidth, videoHeight, 1.1, [-2,-2,-2,0,0,0,2,2,2]);
var effect = new THREE.ShaderPass(ef.shader);
composer.addPass(effect);
var copyPass = new THREE.ShaderPass(THREE.CopyShader);
// copyPass.renderToScreen = true;
composer.addPass(copyPass);
//New scene
sceneF = new THREE.Scene();
sceneF.add(camera);
var videoMesh2 = new THREE.Object3D();
sceneF.add(videoMesh2);
var geomF = new THREE.PlaneGeometry(1, 1);
var materialF = new THREE.MeshBasicMaterial({map: videoTexture});
var meshF = new THREE.Mesh(geomF, materialF);
sceneF.add(meshF);
fcomposer2 = new THREE.EffectComposer(renderer );
fcomposer2.addPass(new THREE.RenderPass(sceneF, camera));
fcomposer2.addPass(simEffect);
var ef1 = new MyShader.Class(videoWidth, videoHeight, [yMaxL,yMinL,xMaxL,xMinL,yMaxR,yMinR,xMaxR,xMinR], videoTexture);
var effect1 = new THREE.ShaderPass(ef1.shader);
fcomposer2.addPass(effect1);
var copyPass2 = new THREE.ShaderPass(THREE.CopyShader);
copyPass2.renderToScreen = true;
fcomposer2.addPass(copyPass2);
animate();
}
// animation loop
function animate() {
// loop on request animation loop
// - it has to be at the begining of the function
requestAnimationFrame(animate);
// do the render
render();
stats.update();
if ((frame % 50) == 0) {
console.log("frame ", frame, " ");
console.log("yMaxL: ", yMaxL, " ");
console.log("yMinL: ", yMinL, " ");
console.log("xMaxL: ", xMaxL, " ");
console.log("xMinL: ", xMinL, " ");
console.log("yMaxR: ", yMaxR, " ");
console.log("yMinR: ", yMinR, " ");
console.log("xMaxR: ", xMaxR, " ");
console.log("xMinR: ", xMinR, " ");
manipulatePixels();
}
frame = frame + 1;
yMaxL = 0, yMinL = 0, yMaxR = 0, yMinR = 0;
xMaxL = 0, xMinL = 0, xMaxR = 0, xMinR = 0;
}
// render the scene
function render() {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
videoTexture.needsUpdate = true;
}
// actually render the scene
renderer.clear();
composer.render();
var left_x = new Array();
var left_y = new Array();
var l = 0;
var right_x = new Array();
var right_y = new Array();
var r = 0;
if (frame == 200) {
var imagedata2 = getImageData(renderer.domElement);
var middle = imagedata2.width / 2;
for (var x=x_min; x < x_max; x=x+1) {
for (var y=y_min; y < y_max; y=y+1) {
var pixel = getPixel(imagedata2, x, y);
if (pixel.g > 0)
{
//console.log(pixel);
if (x < middle) {
left_x[l] = x;
left_y[l] = y;
l++;
}
else {
right_x[r] = x;
right_y[r] = y;
r++;
}
}
}
}
lineEquation(left_x, left_y, right_x, right_y);
}
fcomposer2.render();
}
function lineEquation(left_x,left_y,right_x,right_y) {
var newYMAX = left_y[0];
var newYMIN = left_y[0];
var maximosL = new Array();
var minimosL = new Array();
//left
for (var i=1; i < left_y.length; i++) {
if (left_y[i]>newYMAX) newYMAX = left_y[i];
else {
if (left_y[i]<newYMIN) newYMIN = left_y[i];
}
}
yMaxL = newYMAX;
yMinL = newYMIN;
// yMaxL = ymaxL/videoHeight;
// yMinL = yminL/videoHeight;
var pmin=0, pmax=0;
for (var i=0; i < left_y.length; i++) {
if (left_y[i] === newYMAX) {
// console.log(left_y[i]);
// console.log(left_x[i]);
maximosL[pmax] = left_x[i];
pmax++;
}
}
for (var j=0; j < left_y.length; j++) {
if (left_y[j] === newYMIN) {
// console.log(left_y[j]);
// console.log(left_x[j]);
minimosL[pmin] = left_x[j];
pmin++;
}
}
// console.log(maximosL);
// console.log(minimosL);
var sumMAX = 0, sumMIN = 0;
for (var i=0; i< maximosL.length; i++) {
sumMAX = sumMAX + maximosL[i];
}
for (var j=0; j< minimosL.length; j++) {
sumMIN = sumMIN + minimosL[j];
}
xMaxL = sumMAX/maximosL.length;
xMinL = sumMIN/minimosL.length;
// xMaxL /= videoWidth;
// xMinL /= videoWidth;
//right
var maximosR = new Array();
var minimosR = new Array();
newYMAX = right_y[0];
newYMIN = right_y[0];
pmin=0; pmax=0;
for (var i=0; i < right_y.length; i++) {
if (right_y[i]> newYMAX) newYMAX = right_y[i];
else {
if (right_y[i]< newYMIN) newYMIN = right_y[i];
}
}
yMaxR = newYMAX;
yMinR = newYMIN;
// yMaxR = ymaxR/videoHeight;
// yMinR = yminR/videoHeight;
for (var i=0; i < right_y.length; i++) {
if (right_y[i] === newYMAX)
{maximosR[pmax] = right_x[i]; pmax++;}
if (right_y[i] === newYMIN)
{minimosR[pmin] = right_x[i]; pmin++;}
}
// console.log(maximosR);
// console.log(minimosR);
xMaxR=0;
for (var i=0; i< maximosR.length; i++) {
xMaxR += maximosR[i];
}
xMinR=0;
for (var i=0; i< minimosR.length; i++) {
xMinR += minimosR[i];
}
// console.log(xMaxR);
// console.log(xMinR);
xMaxR /= maximosR.length;
xMinR /= minimosR.length;
// console.log(xMaxR);
// console.log(xMinR);
// xMinR /= videoWidth;
// xMaxR /= videoWidth;
}
function manipulatePixels() {
// imagem antes
var imagedata = getImageData(videoTexture.image);
// imagem processada
var imagedata2 = getImageData(renderer.domElement);
// console.log(getPixel(imagedata, 480 - 1, 270 - 1));
// console.log(getPixel(imagedata2, 480 - 1, 270 - 1));
}
function getImageData(image) {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
return context.getImageData(0, 0, image.width, image.height);
}
function getPixel(imagedata, x, y) {
var position = (x + imagedata.width * y) * 4, data = imagedata.data;
return {r: data[ position ], g: data[ position + 1 ], b: data[ position + 2 ], a: data[ position + 3 ]};
}
function findLineByLeastSquares(values_x, values_y) {
var sum_x = 0;
var sum_y = 0;
var sum_xy = 0;
var sum_xx = 0;
/*
* We'll use those variables for faster read/write access.
*/
var x = 0;
var y = 0;
var values_length = values_x.length;
if (values_length != values_y.length) {
throw new Error('The parameters values_x and values_y need to have same size!');
}
/*
* Nothing to do.
*/
if (values_length === 0) {
return [ [], [] ];
}
/*
* Calculate the sum for each of the parts necessary.
*/
for (var v = 0; v < values_length; v++) {
x = values_x[v];
y = values_y[v];
sum_x += x;
sum_y += y;
sum_xx += (x*x);
sum_xy += (x*y);
}
console.log (sum_x);
console.log(sum_y);
console.log(sum_xx);
console.log(sum_xy);
console.log(values_length);
/*
* Calculate m and b for the formular:
* y = x * m + b
*/
var m = (sum_x*sum_y - values_length*sum_xy) / (sum_x*sum_x - values_length*sum_xx);
var b = (sum_y - (m*sum_x))/values_length;
//console.log([m,b]);
return [m, b];
}
//resize method
/**window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
} */
</script>
Edit2 : Some images of what i'm trying to do: Image 1 shows the results from composer on the console, the limits i get from the lineEquation function are the correct ones for what i intend to do, but in Image 2 shows the results from fcomposer2 (fixed area) and on the console, the limits are the wrong ones.
![Image1]: http://prntscr.com/1ays73
![Image2]: http://prntscr.com/1ays0j
Edit3 :
By "access" i mean to be able to read the values of the pixels from the texture created by the binaryShader.
For example, in image1 the lines are painted in blue/green tone, I wanted to search the position of the pixels (x,y) in the image that the renderTarget would save. If i could find those pixels, i could adapt the green area in image2 to fit between the road lines.
This processing is need to make the green area overlap the current driving lane the user is currently on, if i can't get those points, i can't identify a lane.
I got it to work. Apparently i forgot to declare the fcomposer2 in the beginning of the script.
Thanks for the responses/comments, and sorry for the inconvenience.

Faulty Logic in this image color equalization algorithm

Somewhere in my code, I seem to be doing something wrong and I cannot tell which part is going awry. I've printed to console the values I'm getting from the various arrays and it seems to match up. Then when I run the equalization function (a la Wikipedia-Histogram Equalization) my output image is close to total black. I was trying to interpret this guy's php into javascript just to test some stuff out and figured I did a decent job. But I'm not an expert.
The pertinent parts:
function imageLoaded(ev) {
element = document.getElementById("canvas1");
c = element.getContext("2d");
im = ev.target; // the image
// read the width and height of the canvas
width = element.width;
height = element.height;
// stamp the image on the left of the canvas:
c.drawImage(im, 0, 0);
// get all canvas pixel data
imageData = c.getImageData(0, 0, width, height);
w2 = width / 2;
var reds = new Array();
var greens = new Array();
var blues = new Array();
var freqR = new Array();
var freqG = new Array();
var freqB = new Array();
if (imageData){
buildHistograms(reds, greens,blues);
buildFrequencies(reds, greens, blues, freqR, freqG, freqB);
}
var alpha = 255/(w2*height);
// run through the image
for (y = 0; y < height; y++) {
inpos = y * width * 4; // *4 for 4 ints per pixel
outpos = inpos + w2 * 4;
for (x = 0; x < w2; x++) {
//reads pixel data(of img c)to each channel of rgb
r = imageData.data[inpos++];
g = imageData.data[inpos++];
b = imageData.data[inpos++];
a = imageData.data[inpos++];
//using histogram eqalization formula:
adjR = freqR[r]*alpha;
adjG = freqG[g]*alpha;
adjB = freqB[b]*alpha;
//assigns pixel data of output image
imageData.data[outpos++] = adjR;
imageData.data[outpos++] = adjG;
imageData.data[outpos++] = adjB;
imageData.data[outpos++] = a;
}
}
// put pixel data on canvas
c.putImageData(imageData, 0,0);
}
im = new Image();
im.onload = imageLoaded;
im.src = "Lenna.png";
function buildHistograms(reds,greens,blues){
//run through image building histogram
for (y=0; y < height; y++){
inpos = y * width *4;
for (x=0; x < w2; x++){
rd = imageData.data[inpos++];
g = imageData.data[inpos++];
b = imageData.data[inpos++];
a = imageData.data[inpos++];
// Add counts to our histogram arrays for each color.
reds.push(rd);
greens.push(g);
blues.push(b);
}
}
// Sort them by keys into order
reds.sort(function(a,b){return a-b});
greens.sort(function(a,b){return a-b});
blues.sort(function(a,b){return a-b});
}
function buildFrequencies(reds, greens, blues, freqR, freqG, freqB){
// Build frequency charts for all colors: takes REDS GREENS BLUES from buildHistograms and places them on top of each other accordingly
for(i=0; i<=255; i++){
sumR=0;
sumG=0;
sumB=0;
for(j=0; j<= i; j++){
if (reds[j]){sumR+=reds[j];}
if (greens[j]){sumG+=greens[j];}
if (blues[j]){sumB+=blues[j];}
}
freqR[i] = sumR;
freqG[i] = sumG;
freqB[i] = sumB;
}
}
Any help is appreciated, Thanks.
Looks like my build frequencies section was all wrong. I modified it in this way:
var len = reds.length;
for (j=0; j < len; j++) {
var rCurrVal = reds[j];
var gCurrVal = greens[j];
var bCurrVal = blues[j];
if (freqR.hasOwnProperty(rCurrVal)) {
freqR[rCurrVal] += 1;
} else {
freqR[rCurrVal] = 1;
}
if (freqG.hasOwnProperty(gCurrVal)) {
freqG[gCurrVal] += 1;
} else {
freqG[gCurrVal] = 1;
}
if (freqB.hasOwnProperty(bCurrVal)) {
freqB[bCurrVal] += 1;
} else {
freqB[bCurrVal] = 1;
}
}
for (i=0; i<255; i++){
if ($.inArray(i,reds)===-1){freqR[i]=0;}
if ($.inArray(i,greens)=== -1){freqG[i]=0;}
if ($.inArray(i,blues)=== -1){freqB[i]=0;}
if (i>0){
freqR[i]+=freqR[i-1];
freqG[i]+=freqG[i-1];
freqB[i]+=freqB[i-1];
}
}

Categories

Resources