Я столкнулся со следующей проблемой:
Мы получили много технических чертежей только черного и белого цвета. Такой рисунок содержит несколько объектов в одном изображении. Я закодировал детектор краев и сумел нарисовать линию / обрезать границу каждого отдельного объекта с помощью координат (полигонов).
Моя проблема в том, что я не могу найти способ git, чтобы сохранить только Обрезать области для отдельных файлов изображений.
Мне нужен каждый объект, так как это собственное изображение (например, jpg) без лишних пробелов вокруг объекта.
В целях тестирования я в настоящее время использую изображение Я написал ниже
Так выглядит мой текущий вывод, границы отмечены красным. Сначала пришлось инвертировать цвета, не обращайте на это внимания
var http = require('http')
var fs = require('fs')
var Canvas = require('canvas');
function pixelIsTouching (coord1, coord2){
if(coord1[0] == coord2[0] &&
(coord1[1] == coord2[1]+1 ||
coord1[1] == coord2[1]-1)){
return true;
}else if(coord1[1] == coord2[1] &&
(coord1[0] == coord2[0]+1 ||
coord1[0] == coord2[0]-1)){
return true;
}else{
return false;
}
}
http.createServer(function (req, res) {
fs.readFile(__dirname + '/images/multistar.jpg', function(err, data) {
if (err) throw err;
var img = new Canvas.Image; // Create a new Image
img.src = data;
var canvas = Canvas.createCanvas(img.width, img.height);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
var pixeldata = ctx.getImageData(0, 0, img.width, img.height);
// Filter out any black white noise + Invert
for(var x = 0; x < pixeldata.data.length; x+=4){
if( pixeldata.data[x] > 127) {
pixeldata.data[x] = 0;
pixeldata.data[x+1] = 0;
pixeldata.data[x+2] = 0;
}else if(pixeldata.data[x] <= 127) {
pixeldata.data[x] = 255;
pixeldata.data[x+1] = 255;
pixeldata.data[x+2] = 255;
}
}
ctx.putImageData(pixeldata, 0, 0);
var border = [];
// Bilddaten pixelweise abarbeiten
for (x = 0; x < pixeldata.width; x++) {
for (y = 0; y < pixeldata.height; y++) {
offset = (pixeldata.width * y + x) * 4;
r = pixeldata.data[offset]; // rot
g = pixeldata.data[offset + 1]; // grün
b = pixeldata.data[offset + 2]; // blau
a = pixeldata.data[offset + 3]; // Transparenz
topOffset = (pixeldata.width * (y-1) + x) * 4;
rTop = pixeldata.data[topOffset];
topRightOffset = (pixeldata.width * (y-1) + (x+1)) * 4;
rTopRight = pixeldata.data[topRightOffset];
rightOffset = (pixeldata.width * y + (x+1)) * 4;
rRight = pixeldata.data[rightOffset];
bottomRightOffset = (pixeldata.width * (y+1) + (x+1)) * 4;
rBottomRight = pixeldata.data[bottomRightOffset];
bottomOffset = (pixeldata.width * (y+1) + x) * 4;
rBottom = pixeldata.data[bottomOffset];
bottomLeftOffset = (pixeldata.width * (y+1) + (x-1)) * 4;
rBottomLeft = pixeldata.data[bottomLeftOffset];
leftOffset = (pixeldata.width * y + (x-1)) * 4;
rLeft = pixeldata.data[leftOffset];
topLeftOffset = (pixeldata.width * (y-1) + (x-1)) * 4;
rTopLeft = pixeldata.data[topLeftOffset];
// Check around current white pixel if black one is near
if( r == 255 && rTop == 0 ||
r == 255 && rTopRight == 0 ||
r == 255 && rRight == 0 ||
r == 255 && rBottomRight == 0 ||
r == 255 && rBottom == 0 ||
r == 255 && rBottomLeft == 0 ||
r == 255 && rLeft == 0 ||
r == 255 && rTopLeft == 0){
border.push([x, y]);
}
}
}
//Order border array
var borderscounter = 0;
var borders = [[]];
var coordFound = undefined;
borders[borderscounter].push(border[0]);
border.shift();
while(border.length > 0){
coordFound = false;
for(a = 0; a < border.length; a++){
lastBlobElement = borders[borderscounter].length-1;
if(pixelIsTouching(border[a], borders[borderscounter][lastBlobElement])){
coordFound = true;
borders[borderscounter].push(border[a]);
border.splice(a, 1);
}
}
if(coordFound == false && border.length > 0){
borderscounter++;
borders[borderscounter] = [];
borders[borderscounter].push(border[0]);
border.shift();
}
}
// Draw Line via Border Array
ctx.lineWidth = 1;
ctx.strokeStyle = 'red';
ctx.beginPath();
for(b = 0; b < borders.length; b++){
for(var a = 0; a < borders[b].length; a++){
// + 0.5 to get rid of blurry lines
if(a == 0){
ctx.moveTo(borders[b][a][0]+0.5, borders[b][a][1]);
}else{
ctx.lineTo(borders[b][a][0]+0.5, borders[b][a][1]);
}
if(a == borders[b].length-1){
ctx.closePath();
}
}
}
ctx.stroke();
//ctx.globalCompositeOperation = 'destination-out';
// Crop images via coordinates
ctx.beginPath();
ctx.moveTo(borders[0][0][0], borders[0][0][1]);
for(var i = 1; i < borders[0].length; i++){
var p = borders[0][i];
ctx.lineTo(borders[0][i][0], borders[0][i][1]);
}
ctx.closePath();
ctx.clip();
// save images as files
var file = canvas.toDataURL("image/png");
var data = file.replace(/^data:image\/\w+;base64,/, "");
var buf = new Buffer(data, 'base64');
fs.writeFile('cropped/image.png', buf);
res.write('<html><body>');
res.write('<img src="' + canvas.toDataURL() + '" />');
res.write('</body></html>');
res.end();
});
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');