Dealing with MarvinJ to calculate the black pixels in an image - javascript

I am looking for a method to get the total number of the fully black pixels 100% in an image taken for a cracked concrete to be able to calculate the total surface area of the cracks in order to do other calculations in my masters. I've tried MarvinJ threshold filter to filter out the unwanted colors and let only blacks and whites. the main problem is there are too mant pixels falling outside the cracks area. I am looking for a way to get red of these black pixels manually. Can I select them manually and convert them to white pixels?
<!DOCTYPE html>
<head>
<script src="https://www.marvinj.org/releases/marvinj-1.0.js"></script>
</head>
<body>
<canvas id="canvas" width="500px" height="300px"></canvas>
<canvas id="canvas2" width="500px" height="300px"></canvas>
<input id="threshold" placeholder="threshold value" type="number" step="5" value="140"/>
<input id="blackPixels" placeholder="blackPixels"/>
</body>
canvas {
border: 2px solid #ddd;
}
var canvas = document.getElementById("canvas");
var original = new MarvinImage();
let thresholdingInput = document.getElementById("threshold");
convertNow();
function convertNow(){original.load("https://blog.master-builders-solutions.com/hs-fs/hubfs/BASF%20Blog/imgs/concrete-crack-body.jpg?width=522&name=concrete-crack-body.jpg", thresholding);}
function thresholding(){
// Draw the original image
imageOut = new MarvinImage(original.getWidth(), original.getHeight());
original.draw(canvas);
Marvin.thresholding(original, imageOut, thresholdingInput.value);
imageOut.draw(canvas2);
let comp = [];
for(var y=0; y < imageOut.getHeight(); y++){
for(var x=0; x < imageOut.getWidth(); x++){
var red = imageOut.getIntComponent0(x,y);
var green = imageOut.getIntComponent1(x,y);
var blue = imageOut.getIntComponent2(x,y);
if(red >= 250 && blue >= 250 && green >= 250){
comp.push(true);
}
}
}
let all = Number(imageOut.getWidth())*Number(imageOut.getHeight());
all = all - comp.length;
document.getElementById("blackPixels").value = 'black pixels = ' + all;
}
thresholdingInput.onchange = function(){convertNow()}

Related

How can I control the RGB of my canvas so that the Red and Green part of the gradient is the position of my mouse position divided by two?

My HW instruction specifically calls for this: RGB where red is 0, green is the x-coordinate divided by 2, and blue is the y-coordinate divided by two. So far, my big canvas' colors are controlled by addColorStop functions but I'm not sure how to get the colors to change and how it should change. Any help is appreciated as I have been stuck on this for 2 days. Thanks.
<!DOCTYPE html>
<html>
<body>
<canvas id="big" onclick="myFiller(event);"; width="512" height="512"style="border: solid #000000;"></canvas>
<canvas id="small" width="100" height="100" style="background-color: #FF0000"></canvas>
<p id="para"></p>
<script>
// add eventListener
var c = document.getElementById("big");
var ctx = c.getContext("2d");
var rgbCanvas = ctx.createLinearGradient(c.width, c.height, 120,120);
rgbCanvas.addColorStop(0, "red");
rgbCanvas.addColorStop(0.5 ,"green");
rgbCanvas.addColorStop(1, "blue");
ctx.fillStyle = rgbCanvas;
ctx.fillRect(0,0, 512, 512);
var s = document.getElementById("small");
var stx = s.getContext("2d");
function myFiller(event) {
console.log("running");
// document.getElementById("big").innerHTML = style
// console.log(cData);
var x = event.offsetX;
var y = event.offsetY;
var pixelContainer = ctx.getImageData(x, y, 1, 1).data; //pixelContainer grabs the context of "big" canvas but only one pixel worth
console.log(pixelContainer); //just to see if pixelContainer is working
console.log(pixelContainer[0],pixelContainer[1],pixelContainer[2],pixelContainer[3])
//understand what this is later
document.getElementById("big").innerHTML = "(" + pixelContainer[0] + " " + ")";
var red = (pixelContainer[0]).toString(16);
var green = (pixelContainer[1]).toString(16);
var blue = (pixelContainer[2]).toString(16);
document.getElementById("para").innerHTML = "#"+ red+green+blue;
}
</script>
</body>
</html>
This is a straightforward way to have the background color of the canvas change on mousemove
rif: mousemove MDN
document.querySelector('canvas').addEventListener('mousemove', evt =>
evt.target.style.backgroundColor = `rgb(${evt.offsetX / 2}, ${evt.offsetY / 2}, 0)`
)
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<canvas width="512" height="512"></canvas>
</body>
</html>

Getting pixel values of images in p5js

I have been working on some code that is supposed to draw a dot(ellipse) on each pixel that is black. I am new to the get function, and suspect that I might have made a mistake using it. Does anyone know why my code cannot successfully "dot" the map of India?
function setup() {
createCanvas(400, 400);
}
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("map");
ctx.drawImage(img, 10, 10, 150000, 1800000);
}
function draw() {
for (var x = 0; x < 100; x++){
for (var y = 0; y < 100; y++){
if(black(get(x,y))==255){
ellipse(x , y, 10, 100);
}
}
}
}
<style>
p {
position:absolute;
z-index:3;
}
img {
position:absolute;
z-index: -1;
}
</style>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- PLEASE NO CHANGES BELOW THIS LINE (UNTIL I SAY SO) -->
<script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
<script language="javascript" type="text/javascript" src="p5js-temp-sadfsfdsad8981306098870070843.js"></script>
<!-- OK, YOU CAN MAKE CHANGES BELOW THIS LINE AGAIN -->
<!-- This line removes any default padding and style.
You might only need one of these values set. -->
<style> body { padding: 0; margin: 0; } </style>
</head>
<body>
<img id="map" width="220" height="277" src="https://geology.com/world/india-map.gif" alt="The map">
<!--<img src="https://geology.com/world/india-map.gif">-->
<p id="area"></p> <br>
<p id="perimeter"></p>
</body>
</html>
Edit: I changed the code to
window.onload = function() {
var c = canvas;
var ctx = c.getContext("2d");
var img = document.getElementById("map");
ctx.drawImage(img, 10, 10, 150000, 1800000);
}
function draw() {
for (var x = 0; x < 100; x++){
for (var y = 0; y < 100; y++){
if(black(get(x,y))==255){
ellipse(x , y, 10, 100);
}
}
}
}
<style> body { padding: 0; margin: 0; } </style>
</head>
<body>
<img id="map" width="220" height="277" src="https://geology.com/world/india-map.gif" alt="The map">
<!--<img src="https://geology.com/world/india-map.gif">-->
<p id="area"></p> <br>
<p id="perimeter"></p>
</body>
</html>
<style>
p{
position:absolute;
z-index:3;
}
img{
position:absolute;
z-index: -1;
}
</style>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
<script language="javascript" type="text/javascript" src="p5js-temp-sadfsfdsad1466343293693433275.js"></script>
<!-- This line removes any default padding and style.
You might only need one of these values set. -->
However, I get a black rectangle on the map and no dots. Does anyone know why this is happening?
A somewhat minor tweak of Nick Parson's excellent answer, but one that uses pixels rather than get. It runs almost instantly, which shows that get() is the culprit.
//tweak of Code from Nick Parsons
let img;
function preload() {
img = loadImage('india-map.gif');
}
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
image(img, 0, 0, width, height);
loadPixels();
const d = pixelDensity();
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
const i = 4 * d*(y * d*width + x);
const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]]; // get colors
if (r <= 80 && b <= 80 && g <= 80) { // if r g b all less than 80 then color will appear black
noStroke();
fill(255, 0, 0);
ellipse(x, y, 1);
}
}
}
noLoop();
}
Since you're using p5js you should use the methods and functions it has to offer. There is no need to get the canvas like you are when using p5js. p5js provides a reference to it when you type canvas.
At the moment you are using an image tag to display your image. Instead, you want to display the image to the canvas. You can do this by using p5's preload method to load the image. Then, once it has been loaded, you can reference it in your draw method.
Your draw method will constantly run on a loop. However, you don't need a loop as you only need to do your computations once. Thus you can use p5's method noLoop() to stop draw from looping.
Lastly, to get the color of a particular pixel you need to use get(x, y). This will give you an array of red, green, and blue values. A black pixel is where all three of these values are 0. However, your image has pixels which are not strictly black. For example, if your r g b (red, green, blue) color values are 1, 1, 1 your color would still look black. Thus, to check if a given color is black, you need to check if all these values are less than a particular number such as 80.
If you incorporate all these ideas into your code you should end up with something like this:
let img;
function preload() {
img = loadImage('india-map.gif');
}
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
image(img, 0, 0, width, height);
for(let x = 0; x < width; x++) {
for(let y = 0; y < height; y++) {
const [r, g, b] = get(x, y); // get colors
if(r <= 80 && b <= 80 && g <= 80) { // if r g b all less than 80 then color will appear black
noStroke(); // remove black outline from thing we are about to draw (the ellipse)
fill(255, 0, 0); // make the ellipse red
ellipse(x, y, 1); // draw the ellipse at the pixle
}
}
}
noLoop();
}
You can find a working example here. But please note, this is for demonstration purposes. Please take the time to understand the code. Also, as we are looking at every pixel's color on the canvas using get this takes a LONG time to compute once ran. (consider looking at every 2nd pixel and drawing the ellipse a little larger)

FATAL ERROR syntax error, unexpected '<', expecting end of file on line number 1

Can anyone please help me identify why this code isn't working? It's copied directly from a youtube tutorial so I can't see where I've gone wrong!
Thank you!
I basically want to create matrix rain, but my own version of symbols within it. Would someone be able to correctly identify what's wrong with this code? I have tried to input it into http://phptester.net/
<DOCTYPE html>
<html>
<head>
<title>Matrix Rain</title>
<style>
/*basic resets */
* {margin:0; padding: 0;}
/* adding a black bg to the background to make things clearer */
body {background: black;}
canvas {display: block;}
</style>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript">
var c = document.getElementbyId("c");
var ctx = c.getCont("2d");
//making the canvas full screen
c.height = window.innerHeight;
c.width = windows.innerWidth;
var ganoti = "诶比西迪艾弗艾尺艾勒艾娜吉吾艾儿"
//converting the string into an array of single characters
chinese = chinese.split ("");
var font_size = 10;
var columns = c.width/font_size; //number of columns for rain
//an array of drops - one for column
var drops = [];
//x below is the x coordinate
//1 = y co-ordinate of the drop(same for every drop initially)
for (var = x; x < columns; x++)
drops[x] = 1;
//drawing the characters
function draw () {
//Black BG for the canvas
//translucent BG to show trail
ctx.fillStyle - "rgba(0,0,0,0.05)";
ctx.fillRect(0,0, c.wdith, c.height);
ctx.fillstyle = "DB7093";
ctx.font = font_size + "px arial";
//looping over drops
for (var i = 0; i < drops.length; i++) {
var text = ganoti[Math.floor(Math.random()*ganoti.lenth)];
//x = i*font_size, y = value of drops[i]*font_size
ctx.fillText(text, i*font_size, drops[i]*font_size);
//sending the drop back to the top randomly after it has crossed
screen // it should be in comment line
//adding a randomness to the reset to make the drops scattered on the
Y axis // it should be in comment line
if (drops[i]*font_size > c.height && Math.random() > 0.975)
drops[i] = 0;
//incrementing Y coordinate
drops[i]++
}
}
setInterval(draw, 33);
</script>
</body>
</html>
}
}
phptester.net requires PHP, your code is HTML, besides has redundant double } in the end.

Rotate text in a canvas with javascript

In the following code i want to rotate the text of each element of the array in javascript. If i use for example ctx.rotate(Math.PI/10) before the filltext, it rotates all the elements. The positioning of the text also changes with ctx.rotate(Math.PI/10) and if i use 90 degrees, ctx.rotate(Math.PI/2) the text does not show on the canvas.
<html>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var x = new Array("Day1","Day2","Day3","Day4","Day5");
ctx.rotate(Math.PI/10);
for(var i = 0; i < x.length; i++){
ctx.fillText(x[i],i*50+20,50);
}
</script>
</html>
As i said, i want to rotate each element on its own and with that the positioning of each element should stay the same as in the non-rotated text as in the code above. Thus each element has to rotate around its own axis. How can i achieve this?
Have made some changes in your code, it should help:
<html>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid
#d3d3d3;"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var x = new Array("Day1","Day2","Day3","Day4","Day5");
for(var i = 0; i < x.length; i++){
var size = ctx.measureText(x[i]);
ctx.save();
var tx = (i*50+20) + (size.width/2);
var ty = (50);
ctx.translate(tx,ty);
ctx.rotate(Math.PI / 10);
ctx.translate(-tx,-ty);
ctx.fillText(x[i],i*50+20,50);
ctx.restore();
}
</script>
</html>
Demo: http://jsfiddle.net/m1erickson/YyN2P/
A brief overview:
context.translate to where you want the rotation point of the text
context.rotate
context.fillText with an X offset == 1/2 the text width and Y offset == 1/2 the text height
(you can context.measureText to measure the text width)
wrap all this in context.save and context.restore.
use requestAnimationFrame to drive your animation.
And some example code:
var word1="Day1";
var word1Width=ctx.measureText(word1).width;
var r=0;
animate();
function animate(){
requestAnimationFrame(animate);
r+=Math.PI/180;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.translate(100,100);
ctx.rotate(r);
ctx.fillText(word1,-word1Width/2,4);
ctx.restore();
}

using htmt5 gradient and javascript, simulate wood grain

have a chess board in TABLE, each square a TD.
how would one use html5 gradients (and javascript for randomness) to create a wood texture background for the dark squares?
I'm grabbing a big wood texture (change to one you like) and grabbing a random piece of it at 50% opacity, then underneath is a random brownish color to add a unique undertone to each square. You can adjust all these to get an effect you want. I messed with some gradients and they looked silly.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<style>
div {
width: 100px; height: 100px; margin: 1px;
}
div.texture {
background: url(http://gallery.hd.org/_exhibits/textures/wood-grain-closeup-1-DHD.jpg);
opacity:0.4; filter:alpha(opacity=100);
}
</style>
<script>
$(function(){
$('div.bg').each(function(){
// make each square a random brown
var browns = new Array('CD853F','8B4513','A0522D');
var col = Math.floor(Math.random()*3);
$(this).css('background-color',browns[col]);
// the dimensions of your texture minus square size
var image_width = 500;
var image_height = 400;
// get a random positions
var x = Math.floor(Math.random()*image_width);
var y = Math.floor(Math.random()*image_height);
// make them negative
x = x - (x * 2);
y = y - (y * 2);
var d = $(this).children('div.texture');
d.css('background-position', x+'px'+' '+y+'px');
});
});
</script>
<div class='bg'><div class='texture'></div>
<div class='bg'><div class='texture'></div>

Categories

Resources