Copy link to clipboard
Copied
Hi everyone
can anyone help me with this problem?
I have several of these irregular shaped areas. Now I would need to calculate the midpoint of the areas in question.
Does anyone have a tutorial or similar how I could do that?
the picture below is an example:
Thanks a lot
Cheers
Copy link to clipboard
Copied
That sounds like something for a specialist tool, not a photo editor. You also need to consider that "midpoint" is ambiguous:
* centre of gravity (if this were a solid of uniform density)
* centre of the smallest containing rectangle aligned with grid
* centre of the smallest containing circle
* point at the centre of the longest line between two points on the outside boundary
* average of a large number of x,y sample points randomly or uniformly arranged inside the shape
* or many more...
Copy link to clipboard
Copied
Hi Michael
I'm wondering what criteria you would use to decide on the midpoint? I keep coming back to it being half way between the extremities when considering the object as a rectangle. If you were to select the area and copy to a new layer. Using Free Transform would place the centre handle at that half way point. Making a copy and reducing it in size, will cause it to reduce around that same centre handle.
I don't think this can be what you are looking for, so it would help — me at least — to know what criteria you want to use.
Copy link to clipboard
Copied
If you want to find the centre of gravity - which would normally be considered the midpoint of an irregular shape, you can do it in Photoshop although it is a little awkward.
1. Draw around your shape with the pen tool to create a shape and fill it with a solid color. Then turn off your image layer.
2. Use Select color range to make a selection of your color and in the histogram, expanded view, ensure Cache level is 1 (if not click the triangle at the top right of the histogram). Then read the number of pixels (in my case 4836668)
3. Calculate half that number of pixels - so for me 2418334
4. Add a white rectangle shape just above the irregular shape layer and position the edge approximately halfway down.
5. Press Ctrl+D to Deselect and select color range again
6.Read the number of pixels in the histogram - remember you must be at cache level 1 so click the warning triangle if not.
7. Move the white rectangle up/down and repeat steps 5 & 6 until you have as close as possible half the pixels as calculated in 3.
8. Drag a guide from the ruler an position it on the edge
9. Move the rectangle so it's vertical edge is across the shape and repeat steps 4-8
10. Your guides are in the centre of gravity so you can now turn off the shape layers and turn the image back on
Like I said - it is a bit awkward - but it does work.
I hope that helps
Dave
Copy link to clipboard
Copied
Good one.
It should be possible to script something on the basis of that approach bit it might not be exactly speedy.
Copy link to clipboard
Copied
The below Script intends to mark that point for a black area on white with two guides (no guarantees, though).
// mark »center« on black are on white.
// based on paul riggott’s code for raw image assessment;
// 2018, use it at your own risk;
#target photoshop
File.prototype.readByte = function() {
return this.read(1).charCodeAt(0);
};
if (app.documents.length > 0) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = app.activeDocument;
var theDup = myDocument.duplicate ("dup", true);
theDup.changeMode (ChangeMode.GRAYSCALE);
theDup.layers[0].posterize(2);
theDup.selection.load(theDup.channels[0], SelectionType.REPLACE, true);
theDup.selection.expand(2);
var theBounds = theDup.selection.bounds;
theDup.crop(theBounds);
theDup.changeMode (ChangeMode.LAB);
var theResult = somethingSomething();
theDup.close (SaveOptions.DONOTSAVECHANGES);
activeDocument = myDocument;
myDocument.guides.add(Direction.VERTICAL, theResult[4] + theBounds[0]);
myDocument.guides.add(Direction.HORIZONTAL, theResult[5] + theBounds[1]);
app.preferences.rulerUnits = originalRulerUnits;
};
//////////////////
function convertByteToSignedByte(num){
var dec = (num | (num % 256))-128
return dec;
};
function convertByteToLum( num){
var dec = Math.round((num/256)*100);
return dec;
};
// get arrays of sums of non-white pixels per line and column;
function somethingSomething (){
if(!documents.length) return;
if(activeDocument.mode != DocumentMode.LAB) {
alert("Please convert this document to Lab mode\r Then re-run this script");
return;
};
var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
try{
var Path = activeDocument.path;
}catch(e){var Path = '~/Desktop';}
var rawFile = new File(Path +"/"+Name +".raw");
saveAsRaw(rawFile);
var len = 0;
var W = activeDocument.width.as('px');
CountW=0;
CountH=0;
rawFile.encoding = 'BINARY';
rawFile.open('r');
// result arrays;
var theLines = new Array;
var theColumns = new Array;
for (var y = 0; y < W; y++) {theColumns.push(0)};
var theLine = 0;
////// work through //////
while(!rawFile.eof){
var theL = 100-(convertByteToLum(rawFile.readByte()));
var theA = convertByteToSignedByte(rawFile.readByte());
var theB = convertByteToSignedByte(rawFile.readByte());
len++;
theColumns[CountW] = theColumns[CountW]+theL/100;
// new line;
if(len % W == 0){
theLines.push(theLine);
theLine = 0;
CountH++;
CountW=0;
}else{
CountW++;
theLine = theLine + (theL/100);
};
};
// remove raw file;
rawFile.close();
rawFile.remove();
var theSum = 0;
var theSumColumn = 0;
for (var x = 0; x < theLines.length; x++) {theSum = theSum + theLines
}; for (var x = 0; x < theColumns.length; x++) {theSumColumn = theSumColumn + theColumns
}; var resultHor = midValue (theLines, theSum);
var resultVer = midValue (theColumns, theSumColumn);
activeDocument.guides.removeAll();
activeDocument.guides.add(Direction.VERTICAL, resultVer);
activeDocument.guides.add(Direction.HORIZONTAL, resultHor);
// return results;
return [theLines, theSum, theColumns, theSumColumn, resultVer, resultHor]
};
function saveAsRaw(file) {
var desc1 = new ActionDescriptor();
var desc2 = new ActionDescriptor();
desc2.putString( charIDToTypeID('FlCr'), "8BIM" );
desc2.putBoolean( charIDToTypeID('ChnI'), true );
desc1.putObject( charIDToTypeID('As '), charIDToTypeID('Rw '), desc2 );
desc1.putPath( charIDToTypeID('In '), new File( file ) );
desc1.putBoolean( charIDToTypeID('Cpy '), true );
executeAction( charIDToTypeID('save'), desc1, DialogModes.NO );
};
//////
function midValue (theArray, theSum) {
var theX = 0;
var theHalf = theSum/2;
for (var n = 0; n < theArray.length; n++) {
theX = theX + theArray
; if (theX == theHalf) {return n+1};
if (theX > theHalf) {
var thePercentage = theX/theSum;
var theDiff = 0.5 + ( ( (theSum - theX) / theSum) - ( (theX - theArray
) / theSum) ) * 0.5 / (theArray / theSum); return n+theDiff};
};
};
Copy link to clipboard
Copied
Illustrator:
1. Select Shape
2. Copy Shape
3. Paste Shape in place
4. Select copy
5. OBJECT-PATH-AVERAGE-BOTH_OK
How to Find the Center of a Star in Adobe Illustrator - YouTube