IMEXPR, IMEDIT, IMREPLACE, FIXPIX: Editing linear features in images
Frank Valdes wrote on Dec 10, 1998
The following is a cool and very powerful way to edit features in an image using IMEXPR. IMEDIT is currently limited to rectangular regions and so is tedious if linear features are not along lines or columns. This discussion shows setting up an expression for the feature to be edited (a line segment) and replacing that region by a value a la IMREPLACE or creating a mask and doing interpolation with FIXPIX. Q: I would like to mask out (remove) saturation spikes which cut across images diagonally without rotating the images. I tried a "brute force" method (rotate 45 deg, replace saturated pixels with imreplace, abd rotate back -45 deg), but was concerned with degraded pixels after the process. However, I was unsuccessful to find an alernative myself. Is there a nice way to do such a thing? Thanks for your help. A: Yes you should not rotate your image because it will degrade the resolution. It will also reduce any spikes and make them harder to find. What I don't understand is if you mean that you want to replace all pixels above some threshold value by another value. IMREPLACE will do this and it does not care about whether the pixels are in a line or column. Maybe you mean that there are diagonal features which may or may not be identifiable as individual pixels above a threshold but are obviously bad because of being a linear feature. There are various ways to do this. Below I give a useful way that you can customize as you need. This uses the powerful task IMEXPR. You will need to read the help for the details. Because the expressions are a little complex use an expression database. cl> type imexpr.db # IMEXPR macros for finding the horizontal distance from a line segment. # The end points are (a,b) and (c,d). Use dx if the line extends across # the entire image. dxend checks for the endpoints. dx(a,b,c,d) (abs(I-(a+(J-b)*(c-a)/(d-b)))) dxend(a,b,c,d) ((J < min(b,d) || J > max(b,d)) ? 1000. : dx(a,b,c,d)) cl> imexpr exprdb=imexpr.db expression: dxend(10,10,90,90) < 2 ? 1 : a ( ( J < min ( 10 , 90 ) || J > max ( 10 , 90 ) ) ? 1000. : ( abs ( I - ( 10 + ( J - 10 ) * ( 90 - 10 ) / ( 90 - 10 ) ) ) ) ) < 2 ? 1 : a output image: junk1 operand a: junk 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% - done The expression database defines the horizontal distance from a line specified by two endpoints. You could generalize this in various ways. The dxend expression provides for checking for endpoints of the line in the image. The example shows replacing all pixels which are less than 2 pixels from the line defined by the endpoints (10,10) and (90,90) by 1. Other ways would be to make a mask image and use FIXPIX. This would allow interpolation. You could use the above example but make the output be a mask image created with certain dimensions. A mask image has a .pl extension and is 0 where there are good pixels and 1 where there are bad pixels. cl> imexpr exprdb=imexpr.db dims=100,100 expression (dxend(10,10,90,90) < 2 ? 1 : a): dxend(10,10,90,90) < 2 ? 1 : 0 ( ( J < min ( 10 , 90 ) || J > max ( 10 , 90 ) ) ? 1000. : ( abs ( I - ( 10 + ( J - 10 ) * ( 90 - 10 ) / ( 90 - 10 ) ) ) ) ) < 2 ? 1 : 0 output image (junk1): mask.pl 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% - done cl> fixpix image mask
Last post on Dec 10, 1998