Tag Info

Hot answers tagged

24

I think the essence of the problem here is that width needs to be counted orthogonally to some best fit line going through the elongated shape. Even naked eye would estimate some non-zero slope. We need to make line completely horizontal on average. We could use ImageLines (see this compact example) but I suggest optimization approach. Import image: i = ...


21

Perhaps this will motivate others or your own much better answer. In the following imr is the rotated image and piece is a piece of texture cropped from the image. It is then placed in an image of same dimension as imr and the in-painted then used to in-paint. id = ImageDimensions[imr]; mask = Erosion[Binarize[MorphologicalComponents[imr] // Colorize], 5]; ...


14

As already commented you can use the Background option for ImageRotate. You might use DominantColors to select a background color. img = Import["http://i.stack.imgur.com/Qr60D.png"]; ImageRotate[img, -50 °, Background -> DominantColors[img, 1]]


14

The answer by Vitaliy is great but his approach has one drawback: ImageRotate introduces artifacts depending on the Resampling method which affects the final estimates for the slit width. A better solution would process the original image data without distorting it. The following approach does not include any artificial manipulations with the original data ...


13

Ouch that's a noisy image! Here goes...a method that isn't WEKA filtering, but seems to work well. First, I had to crop out the white bands at the top/bottom of your image. img = ImageAdjust@ImageCrop[(*OP image*), {223, 223}]; Next, I applied two differently-sized median filters and subtracted one from the other to make the image a bit easier to work ...


9

If you are looking for a quick estimate, you can erode the line until it disappears. The point at which it is gone gives an estimate of the thickness of the original line. In this implementation, adjust the slider until the line is just barely visible. The t parameter is the number of pixels eroded, and so corresponds to the thickness of the line. When I do ...


8

ImageLevels[ ColorConvert[img, "Grayscale"] ][[1, 2]] // RepeatedTiming (* Out: {0.0029, 144316} *) Generally, for speed, you want to avoid pattern matching altogether.


7

If you're looking for a "machine learning" solution, could you describe how the "weka segmentation" works - Mathematica has some machine learning functionality (though not nearly as extensive as WEKA), maybe it's possible to get similar results with Classify. If you're looking for a "classic" fixed filter based approach, you could start with a RidgeFilter, ...


6

Here is a version that should be superior to your attempt. I'm using ImagePartition (as already suggested by m_goldberg) to rip your original image apart at 1/3 of the image width. After that you use a negative ImagePad to remove 20 pixel and again a positive ImagePad to add a 20 pixel white border. For processing a large number of images, it definitely ...


6

You can do this much faster and more easily on the image level using: ImageMeasurements[ColorNegate@Binarize[img, 0], "Total"] // RepeatedTiming {0.0039, 144316.} Another way: Length@ImageValuePositions[img, 0] // RepeatedTiming {0.013, 144316}


6

You didn't post a sample image, so I'll use the Lena test image: img = ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"]; fft = Fourier[ImageData[img]]; fft = RotateLeft[fft, Floor[Dimensions[fft]/2]]; (RotateLeft is basically equivalent to *(-1)^Table[i + j, {i, IRow}, {j, ICol}] in your code: it shifts the 0/0 frequency to the center of the ...


4

All times decrease as you proceed through this answer. The final version takes about 70% of the time of Pickett's solution on this sample problem on my hardware. For comparison, mrz's initial solution: mrz := Length[Position[ImageData[img], {0., 0., 0.}]] mrz // RepeatedTiming (* Out: {0.208, 144316} *) I found a number of much slower ways to do this. ...


3

You can use Count to achieve the same thing. It is slighlty faster on your image, but same order of magnitude execution time: Clear[data] data = ImageData[img]; Length@Position[data, {0., 0., 0.}] // RepeatedTiming Count[data, {0., 0., 0.}, Infinity] // RepeatedTiming (* Out: {0.16, 144316} {0.10, 144316} *)


3

You can apply your transformation to a black image of the same dimension to create a mask. When you add this mask to one of your images the black areas of the mask will not affect them, and the white areas will make the color channel values in those areas of the images one or larger. However, those values will then be truncated back to 1, giving you the ...


1

Following the comments from Oleksandr R.: aux = Import["input.gif"]; i1 = ColorReplace[aux[[1]], Blue -> White, 0.3]; ImageTransformation[#, FindGeometricTransform[ColorReplace[#, Blue -> White, 0.3], i1, TransformationClass -> "Rigid", Method -> {"ImageAlign"}][[2]], DataRange -> Full, Background -> White, Masking -> All] & /@ ...



Only top voted, non community-wiki answers of a minimum length are eligible