|
Prev: unix('command')
Next: position of the max value in a vector
From: Image Analyst on 4 May 2008 09:57 ms <silvertonm(a)gmail.com> wrote in message <8e83d286-2e57- 4c69-b3f9-887db2b85b59(a)r9g2000prd.googlegroups.com>... > On May 3, 7:35=A0pm, ImageAnalyst <imageanal...(a)mailinator.com> wrote: > > On May 3, 9:59=A0pm, ms <silvert...(a)gmail.com> wrote: > > > > > > > > > > > > > On May 2, 2:17=A0pm, ImageAnalyst <imageanal...(a)mailinator.com> wrote: > > > > > > On May 2, 10:33=A0am, ms <silvert...(a)gmail.com> wrote: > > > > > > > Dear Group, > > > > > > > I have three images corresponding to different pressure exerted on > > > > > film (the hard the film is pressed the darker the image). =A0I would= > > > > > > like to use this as calibration to analyze other images. =A0Would an= > yone > > > > > be able to tell me how I would go about this in matlab? > > > > > > Just use polyfit to do some kind of regression to get a polynomial > > > > function that will convert image intensity into real world units such > > > > as pressure. =A0Write back if you still don't understand. =A0I do this= > all > > > > the time converting xray images into "layers of aluminum" or grams per= > > > > > square meter, etc. > > > > ImageAnalyst > > > > > Thank you for the response. =A0Converting xray sounds very interesting! > > > I would use polyfit to calibrate after I am able to pull off the > > > values from each image. =A0The problem is that I do not know how to go > > > about this entire process? =A0For example, I imagine it would go > > > something like this: > > > > > 1. =A0Scan each image using a high resolution scanner (any > > > recommnedations on pixels size?)...now the image is a digital image. > > > 2. =A0Load image into Matlab. > > > 3. =A0The image will be white background with a red pattern depending on= > > > > how hard the film is pressed (light to dark). > > > 4. =A0Convert from color to greyscale (does this need to be done)? > > > 5. =A0Use matlab to determine the signal intensity for each particular > > > image (this is what I really don't know how to do)! > > > > > Any help would be greatly appreciated. =A0Even a specific example using > > > a simple example (like a single black circle on a white background > > > would help me understand). =A0Thanks again! > > > > -------------------------------------------------------- ------------------= > -=AD--------- > > ms: > > Well first, before we get into any of that, what is your reference or > > standard? =A0You have to have some sort of "ground truth" so that you > > know what intensity is represented by what gray level. =A0Can you put > > some kind of known force or pressure on your sensor and get an image > > of it? =A0Without this, you're not calibrating anything accurately - > > you'd just be completely guessing. > > > > Now, a little on your questions: > > 1. =A0It appears that your measurement is an analog image on a paper so > > you're scanning it. =A0Only you know what digital resolution you need. > > 2. =A0Yes. > > 3. =A0OK, fine, but we need to know how much pressure causes how much > > brightness. > > 4. =A0Yes, just take one of the color channels. =A0Use the one that gives > > you the best combination of high contrast and low noise. =A0You'll > > probably get the highest contrast in the blue channel but it may be > > the noisiest. =A0The green channel may be a good compromise. =A0The red > > channel likely will have low contrast since you will have a high red > > signal both in your white background and in your pressure spots. > > 5. =A0This is where you calibration comes in. =A0First you will need to > > have made up your calibration like I talked about above (using known > > pressures and measuring their gray levels, plugging into polyfit and > > getting out the coefficients). =A0Then you can apply the calibration to > > your image to get an image where the values represent actual force > > (pressure) measurements. =A0Use the coefficients from your polyfit > > routine to multiply and add to your scanned-in image so that you have > > the force image. > > Regards, > > ImageAnalyst- Hide quoted text - > > > > - Show quoted text - > > Very helpful! I do have a known weight as my reference for the color > (the color becomes darker with increased weight). I use 10 different > weights, which will be used for calibration. So, I am having a > problem taking the intensity levels off of the image. If I use > imtool, I can visually look at a specific region and determine the > intensity level, but I would like to use code to capture the same > thing. This is where I am at so far: > > 1. image =3D imread('im1.tiff');%loads image > 2. image_gray =3D rgb2gray(image);%converts to gray scale > 3. imshow(image_gray)%displays image > 4. This is where I either manually go in using imtool, or just take > the entire mean of the image (which is wrong because there are areas > filled with 255---completely white) - mean2(image_gray);% mean > intensity of entire image. > > What I would like to do is to be able to use code to "outline" the > image (maybe even break it into a grid of 4 quadrants after segmenting > it as well), and take the mean, max, min of each particular region > (this would be more for images after the calibration occurs). Is this > possible? Would I need to manually outline the image? > > I know this is quite labor intensive to answer these types of > questions...I really appreciate your help. ------------------------------------------------------ ms: For each region, you get the mean. You define the regions by whatever means you want. For me, I have a series of boxes where I keep track of topLine, bottomLine, leftColumn, rightColumn for every box. These 4 numbers are put into an array so that I have an N by 2 array where N is the number of calibration regions in the image. Now, you take the mean of each region. If I recall correctly it's something like for k = 1 : numberOfRegions x1 = boxLocations(k).leftColumn; x2 = boxLocations(k).rightColumn ; y1 = boxLocations(k).topLine; y2 = boxLocations(k).bottomLine; meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); end I have a GUI that lets people move the boxes around and save their locations, as well as a listbox of calibration images that they can read in. Now you make up two arrays of N by 1. The first array (polyfit's "X" array) is the mean gray levels of the regions, for example 50 gray levels, 100 gray levels and so on. The second array (polyfit's "Y" array) is the actual real world pressures that you used for the region, for example 100 grams/m^2, 200 grams/m^2 and so on. for those regions. actualPressures = [100 200 300 and so on]; Feed these both into polyfit (going by memory here since I don't have MATLAB open at the moment) orderOfPolynomial = 2; coefficients = polyfit(meanOfRegions, actualPressures, orderOfPolynomial); and you get out an array of coefficients that tell you how to put in a gray level and get out a pressure. Now you're almost done. Next take an image, say the calibration image or any test image with unknown pressures, and get an output image that is the estimated calibrated pressure image. For example estimatedPressures = coefficient(0) + coefficient(1) * testImage + coefficient(2) * (testImage .* testImage); Now you're done and you can go ahead and process that image in any way that you like and you will be working with real world units. These seem like pretty explicit instructions so hopefully they will be enough for you to use, but write back if you still have questions. Best wishes, ImageAnalyst P.S. Pay attention to what I said in the earlier message about getting the monochrome image from the color image (don't do what you said, unless there is no difference in contrast, which I'm pretty sure is not the case, and you're doing it to reduce the noise).
From: ImageAnalyst on 6 May 2008 22:30 On May 6, 4:24 am, ms <silvert...(a)gmail.com> wrote: > On May 5, 5:21 pm, ImageAnalyst <imageanal...(a)mailinator.com> wrote: > > > > > > > On May 5, 2:39 pm, ms <silvert...(a)gmail.com> wrote: > > > > On May 4, 6:57 am, "Image Analyst" <imageanal...(a)mailinator.com> > > > wrote: > > > > > ms: > > > > For each region, you get the mean. You define the regions > > > > by whatever means you want. For me, I have a series of > > > > boxes where I keep track of topLine, bottomLine, > > > > leftColumn, rightColumn for every box. These 4 numbers are > > > > put into an array so that I have an N by 2 array where N is > > > > the number of calibration regions in the image. Now, you > > > > take the mean of each region. If I recall correctly it's > > > > something like > > > > for k = 1 : numberOfRegions > > > > x1 = boxLocations(k).leftColumn; > > > > x2 = boxLocations(k).rightColumn ; > > > > y1 = boxLocations(k).topLine; > > > > y2 = boxLocations(k).bottomLine; > > > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > > > end > > > > I have a GUI that lets people move the boxes around and > > > > save their locations, as well as a listbox of calibration > > > > images that they can read in. > > > > Now you make up two arrays of N by 1. The first array > > > > (polyfit's "X" array) is the mean gray levels of the > > > > regions, for example 50 gray levels, 100 gray levels and so > > > > on. The second array (polyfit's "Y" array) is the actual > > > > real world pressures that you used for the region, for > > > > example 100 grams/m^2, 200 grams/m^2 and so on. for those > > > > regions. > > > > actualPressures = [100 200 300 and so on]; > > > > Feed these both into polyfit (going by memory here since I > > > > don't have MATLAB open at the moment) > > > > orderOfPolynomial = 2; > > > > coefficients = polyfit(meanOfRegions, actualPressures, > > > > orderOfPolynomial); > > > > > and you get out an array of coefficients that tell you how > > > > to put in a gray level and get out a pressure. Now you're > > > > almost done. Next take an image, say the calibration image > > > > or any test image with unknown pressures, and get an output > > > > image that is the estimated calibrated pressure image. For > > > > example > > > > estimatedPressures = coefficient(0) + coefficient(1) * > > > > testImage + coefficient(2) * (testImage .* testImage); > > > > Now you're done and you can go ahead and process that image > > > > in any way that you like and you will be working with real > > > > world units. > > > > These seem like pretty explicit instructions so hopefully > > > > they will be enough for you to use, but write back if you > > > > still have questions. > > > > Best wishes, > > > > ImageAnalyst > > > > P.S. Pay attention to what I said in the earlier message > > > > about getting the monochrome image from the color image > > > > (don't do what you said, unless there is no difference in > > > > contrast, which I'm pretty sure is not the case, and you're > > > > doing it to reduce the noise).- Hide quoted text - > > > > You have been extremely helpful! Instead of simply using rgb2gray, I > > > tried using image(:,:,2)%this was to look at the blue channel (That is > > > correct, right?). I actually looked at 1,2,3 and noticed that the > > > blue channel was the best out of the three. Is there any disadvantage > > > to this...instead of using rgb2gray (well, that is another story)? > > > Back to "selecting the regions". I understand what to do with the > > > information once each mean is determined for each of the different > > > regions (l think 4 would work in my case)...that is, I would know how > > > to use the polyfit function to create my calibration after both > > > intesity and pressure are both determined. What I don't understand at > > > this point is how you are determining your roi? You sent the code: > > > > > for k = 1 : numberOfRegions > > > > x1 = boxLocations(k).leftColumn; > > > > x2 = boxLocations(k).rightColumn ; > > > > y1 = boxLocations(k).topLine; > > > > y2 = boxLocations(k).bottomLine; > > > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > > > end > > > > (I would then take mean(meanOfRegion) to give me the overall > > > calibration value for this particular image, correct?...I would then > > > perform this for each of the other images to be used for calibration.) > > > > say numberOfRegions = 4; > > > > what are the variables within the loop, such as > > > "boxLocations(k).leftColumn"? I am guessing that these are the x,y > > > values given by your box used to select a region of interest? I was > > > also unfamiliary with the "." seperating the two...is this a > > > particular format? > > > > I tried using the roipoly function in matlab to select an area, but it > > > was somewhat difficult (not an exact box) to use accurately. Is there > > > a function that will display a box on the image, move it around, and > > > resize the box size (I may be asking too much!)? Or is this type of > > > code simple enough to create? > > > > Image Analyst, you have been a terrific help. I thought my post was > > > going to be ignored or minimal input. I hope I can contribute as you > > > have some day!- Hide quoted text - > > > > - Show quoted text - > > > ---------------------------------------------------------------------------------- > > ms: > > No, you misunderstand parts of it. The variables in the loop such as > > boxLocations(k).leftColumn are the lines and columns defining the > > edges of the box. boxLocations is an array so that if you had 4 > > boxes, you would have 4 boxLocations's. boxLocations is a "structure" > > which means that I can call the fields of the structure virtually > > anything I want. Look up "structure" in the help file - it's a type > > of variable. Sure, I could have defined an integer array of > > boxLocations(4,4) where boxLocations(1,1) would be the left column, > > boxLocations(1,2) would be the right column, boxLocations(1,3) would > > be the top line, and boxLocations(1,4) would be the bottom line (all > > for box #1, and similarly for the other boxes), but I chose to use a > > structure instead of an integer array because the structure allows me > > to give descriptive names which make the code much more readable. The > > dot in between the structure name and it's field is what separates the > > structure object from it's fields - same as any other language, it's > > pretty standard. > > > Now, if I had 4 regions, I certainly would not average them together > > like you said except in one very special case: where all your pressure > > regions in your image represent the same pressure. For example, you > > have one image with 4 regions and all 4 regions represent 100 grams > > per square meter (gsm), and maybe you have another image where you > > have 4 regions that are all 200 gsm. Is that what you have? In that > > case, you could average them together. What I was assuming was that > > you had only one calibration image and that image had serveral regions > > all representing DIFFERENT pressures. In that case you can't average > > them together or else you won't have any calibration at all. > > > Other notes: > > The blue image is image(:,:,3) not image(:,:,2) > > I don't know of any MATLAB function to have you draw a box. That > > would be a nice additional utility. Since MATLAB seems to lack that, > > that's why I wrote my own code where I load up the corners of the box > > into x and y arrays and call plot(x,y). You can move the boxes by > > clicking in the image or nudging them with scroll bars. > > Using RGB2gray does a weighted average of the color channels. However > > if one channel is no good, like your red channel which has little > > information in it, then you're averaging in something that will reduce > > your precision. So obviously you don't want to do that. Averaging > > will reduce noise (this is a good thing) so if both your green and > > blue channels look pretty much the same, you can average just those > > two together to reduce your noise and maintain precision. Often in > > digital images the blue channel looks pretty noisy. If that is your > > case, don't use it as it will be worse than using the green channel > > only. So average the green and blue only if both the signal and the > > noise look about the same in each channel, otherwise just take the one > > single best channel, whichever channel that happens to be. > > Regards, > > ImageAnalyst- Hide quoted text - > > > - Show quoted text - > > Image Analyst, > I do have multiple images in which the entire area should be > representative of the load applied; however; there is some differences > near the edges(slightly lighter than most of the image). The image is > a circle that should be representative of the load applied, and I am > breaking this up into 4 different parts (like quadrants of a pie), > taking the average of each quadrant, then taking the overall average. > I would then do this for all 10 different loads. I would then plug > all the values to use polyfit and get a calibration curve. The images > to be used at a later date will likely have un-uniform patterns and > will need to deal with that when that time comes. > > You were correct, the blue channel (:,:,3) was a noisy channel > compared to the green (at least visually to my naked eye...is there a > way to quantify this?). As for the structures, it looks like a very > nice way to organize data...but will take some getting used to...I > only use matrix arrays! I tried averaging the two channels, but kept > having problems as they are in uint8 format. So I would have green > with an intesity of 180 and blue 200, and when I would add them and > divide by 2 the answer would always be 128 (255/2=127.5...I guess it > rounds up). gb = ((image(:,:,2)+image(:,:,2))/2). There must be a > better way? > > As for the box...and being able to nudge it and move it...I was unable > to do so when I used the plot(x,y) function. I plotted the image > (green channel only). created an array for x and y (x=[1 1 10 10 1], > y=[1 10 10 1 1]). I then plotted them over the image (plot(x,y)) and > a blue box appeared in the upper left corner. I was, however, unable > to move the box. > > Thanks again!- Hide quoted text - > > - Show quoted text - ------------------------------------------------------------------------- ms: You don't need to average each quadrant and then average those averages. You can do it all in one shot because the average of the averages is mathematically identical to the average of all the pixels together as one group. You can determine and compare the noise in the two images by simply looking at the standard deviation of each color band. If you want to average 2 uint8's you need to convert them to floating points numbers first because otherwise they can add up to something bigger than uint8 allows (which is 255). So convert each to double, then add together, and divide by 2. Don't convert back into uint8 because there's no need to, and that will just reduce accuracy of your calibration curve. I'll see if maybe tomorrow I can post some code for moving calibration boxes. You can then adapt it to your liking. One improtant consideration is how well your calibration holds up in a non-calibration setting. You say that putting one large weight on the sensor gives a variety of signals with the signal being more consistent in the center and tapering off near the edges. Well which signal should you use? Should you use the average of an area that is some arbitrary distance in from the edges? OK but then what happens in one of your test cases where the weight is only a small part of your sensor area? Maybe you'll never attain the value that you had in the center of your large calibration area because maybe the whole small weight region is "all edges" with the lesser signal strength. So a small weight registers a different signal than a large weight. This complicates your calibration. Maybe your calibration weights should be as small as the resolution you hope to achieve, which will be less than the native sensor resolution due to this "weight tapering off" situation near the edges of the weight. Why does your signal taper off near the edges? I can see the one edge pixel because maybe that pixel is only partially covered by the edge of the weight. Is there some physics reason why, say, a square block would have more force in the middle of the block than at the edges? (I don't know - maybe ask sci.physics) If there is, then you need to take that function into account in your measurement of the signal for the region to get the corrected signal. Are all your sensors independent? Does the signal at one sensor depend on the force applied to its neighboring pixels? Since you say you're using film the answer is that each scanned in pixel is NOT independent and its signal does correlate highly with the signal of its neighbors. Some things to think about if you want to be super accurate. If it's just a homework problem, I wouldn't worry about it but if you're designing something for, say, a civilian airliner or the space shuttle then you better be very, very sure you do it correctly because lives could be at stake. (Kind of reminds me of a QA question I heard once: "Would you fly in an airliner that your software development team wrote the software for?") You can see that this can turn into a much more complicated situation than what you probably first anticipated. Regards, ImageAnalyst
From: ms on 5 May 2008 14:39 On May 4, 6:57 am, "Image Analyst" <imageanal...(a)mailinator.com> wrote: > ms: > For each region, you get the mean. You define the regions > by whatever means you want. For me, I have a series of > boxes where I keep track of topLine, bottomLine, > leftColumn, rightColumn for every box. These 4 numbers are > put into an array so that I have an N by 2 array where N is > the number of calibration regions in the image. Now, you > take the mean of each region. If I recall correctly it's > something like > for k = 1 : numberOfRegions > x1 = boxLocations(k).leftColumn; > x2 = boxLocations(k).rightColumn ; > y1 = boxLocations(k).topLine; > y2 = boxLocations(k).bottomLine; > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > end > I have a GUI that lets people move the boxes around and > save their locations, as well as a listbox of calibration > images that they can read in. > Now you make up two arrays of N by 1. The first array > (polyfit's "X" array) is the mean gray levels of the > regions, for example 50 gray levels, 100 gray levels and so > on. The second array (polyfit's "Y" array) is the actual > real world pressures that you used for the region, for > example 100 grams/m^2, 200 grams/m^2 and so on. for those > regions. > actualPressures = [100 200 300 and so on]; > Feed these both into polyfit (going by memory here since I > don't have MATLAB open at the moment) > orderOfPolynomial = 2; > coefficients = polyfit(meanOfRegions, actualPressures, > orderOfPolynomial); > > and you get out an array of coefficients that tell you how > to put in a gray level and get out a pressure. Now you're > almost done. Next take an image, say the calibration image > or any test image with unknown pressures, and get an output > image that is the estimated calibrated pressure image. For > example > estimatedPressures = coefficient(0) + coefficient(1) * > testImage + coefficient(2) * (testImage .* testImage); > Now you're done and you can go ahead and process that image > in any way that you like and you will be working with real > world units. > These seem like pretty explicit instructions so hopefully > they will be enough for you to use, but write back if you > still have questions. > Best wishes, > ImageAnalyst > P.S. Pay attention to what I said in the earlier message > about getting the monochrome image from the color image > (don't do what you said, unless there is no difference in > contrast, which I'm pretty sure is not the case, and you're > doing it to reduce the noise).- Hide quoted text - You have been extremely helpful! Instead of simply using rgb2gray, I tried using image(:,:,2)%this was to look at the blue channel (That is correct, right?). I actually looked at 1,2,3 and noticed that the blue channel was the best out of the three. Is there any disadvantage to this...instead of using rgb2gray (well, that is another story)? Back to "selecting the regions". I understand what to do with the information once each mean is determined for each of the different regions (l think 4 would work in my case)...that is, I would know how to use the polyfit function to create my calibration after both intesity and pressure are both determined. What I don't understand at this point is how you are determining your roi? You sent the code: > for k = 1 : numberOfRegions > x1 = boxLocations(k).leftColumn; > x2 = boxLocations(k).rightColumn ; > y1 = boxLocations(k).topLine; > y2 = boxLocations(k).bottomLine; > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > end (I would then take mean(meanOfRegion) to give me the overall calibration value for this particular image, correct?...I would then perform this for each of the other images to be used for calibration.) say numberOfRegions = 4; what are the variables within the loop, such as "boxLocations(k).leftColumn"? I am guessing that these are the x,y values given by your box used to select a region of interest? I was also unfamiliary with the "." seperating the two...is this a particular format? I tried using the roipoly function in matlab to select an area, but it was somewhat difficult (not an exact box) to use accurately. Is there a function that will display a box on the image, move it around, and resize the box size (I may be asking too much!)? Or is this type of code simple enough to create? Image Analyst, you have been a terrific help. I thought my post was going to be ignored or minimal input. I hope I can contribute as you have some day!
From: ImageAnalyst on 5 May 2008 20:21 On May 5, 2:39 pm, ms <silvert...(a)gmail.com> wrote: > On May 4, 6:57 am, "Image Analyst" <imageanal...(a)mailinator.com> > wrote: > > > > > > > ms: > > For each region, you get the mean. You define the regions > > by whatever means you want. For me, I have a series of > > boxes where I keep track of topLine, bottomLine, > > leftColumn, rightColumn for every box. These 4 numbers are > > put into an array so that I have an N by 2 array where N is > > the number of calibration regions in the image. Now, you > > take the mean of each region. If I recall correctly it's > > something like > > for k = 1 : numberOfRegions > > x1 = boxLocations(k).leftColumn; > > x2 = boxLocations(k).rightColumn ; > > y1 = boxLocations(k).topLine; > > y2 = boxLocations(k).bottomLine; > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > end > > I have a GUI that lets people move the boxes around and > > save their locations, as well as a listbox of calibration > > images that they can read in. > > Now you make up two arrays of N by 1. The first array > > (polyfit's "X" array) is the mean gray levels of the > > regions, for example 50 gray levels, 100 gray levels and so > > on. The second array (polyfit's "Y" array) is the actual > > real world pressures that you used for the region, for > > example 100 grams/m^2, 200 grams/m^2 and so on. for those > > regions. > > actualPressures = [100 200 300 and so on]; > > Feed these both into polyfit (going by memory here since I > > don't have MATLAB open at the moment) > > orderOfPolynomial = 2; > > coefficients = polyfit(meanOfRegions, actualPressures, > > orderOfPolynomial); > > > and you get out an array of coefficients that tell you how > > to put in a gray level and get out a pressure. Now you're > > almost done. Next take an image, say the calibration image > > or any test image with unknown pressures, and get an output > > image that is the estimated calibrated pressure image. For > > example > > estimatedPressures = coefficient(0) + coefficient(1) * > > testImage + coefficient(2) * (testImage .* testImage); > > Now you're done and you can go ahead and process that image > > in any way that you like and you will be working with real > > world units. > > These seem like pretty explicit instructions so hopefully > > they will be enough for you to use, but write back if you > > still have questions. > > Best wishes, > > ImageAnalyst > > P.S. Pay attention to what I said in the earlier message > > about getting the monochrome image from the color image > > (don't do what you said, unless there is no difference in > > contrast, which I'm pretty sure is not the case, and you're > > doing it to reduce the noise).- Hide quoted text - > > You have been extremely helpful! Instead of simply using rgb2gray, I > tried using image(:,:,2)%this was to look at the blue channel (That is > correct, right?). I actually looked at 1,2,3 and noticed that the > blue channel was the best out of the three. Is there any disadvantage > to this...instead of using rgb2gray (well, that is another story)? > Back to "selecting the regions". I understand what to do with the > information once each mean is determined for each of the different > regions (l think 4 would work in my case)...that is, I would know how > to use the polyfit function to create my calibration after both > intesity and pressure are both determined. What I don't understand at > this point is how you are determining your roi? You sent the code: > > > for k = 1 : numberOfRegions > > x1 = boxLocations(k).leftColumn; > > x2 = boxLocations(k).rightColumn ; > > y1 = boxLocations(k).topLine; > > y2 = boxLocations(k).bottomLine; > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > end > > (I would then take mean(meanOfRegion) to give me the overall > calibration value for this particular image, correct?...I would then > perform this for each of the other images to be used for calibration.) > > say numberOfRegions = 4; > > what are the variables within the loop, such as > "boxLocations(k).leftColumn"? I am guessing that these are the x,y > values given by your box used to select a region of interest? I was > also unfamiliary with the "." seperating the two...is this a > particular format? > > I tried using the roipoly function in matlab to select an area, but it > was somewhat difficult (not an exact box) to use accurately. Is there > a function that will display a box on the image, move it around, and > resize the box size (I may be asking too much!)? Or is this type of > code simple enough to create? > > Image Analyst, you have been a terrific help. I thought my post was > going to be ignored or minimal input. I hope I can contribute as you > have some day!- Hide quoted text - > > - Show quoted text - ---------------------------------------------------------------------------------- ms: No, you misunderstand parts of it. The variables in the loop such as boxLocations(k).leftColumn are the lines and columns defining the edges of the box. boxLocations is an array so that if you had 4 boxes, you would have 4 boxLocations's. boxLocations is a "structure" which means that I can call the fields of the structure virtually anything I want. Look up "structure" in the help file - it's a type of variable. Sure, I could have defined an integer array of boxLocations(4,4) where boxLocations(1,1) would be the left column, boxLocations(1,2) would be the right column, boxLocations(1,3) would be the top line, and boxLocations(1,4) would be the bottom line (all for box #1, and similarly for the other boxes), but I chose to use a structure instead of an integer array because the structure allows me to give descriptive names which make the code much more readable. The dot in between the structure name and it's field is what separates the structure object from it's fields - same as any other language, it's pretty standard. Now, if I had 4 regions, I certainly would not average them together like you said except in one very special case: where all your pressure regions in your image represent the same pressure. For example, you have one image with 4 regions and all 4 regions represent 100 grams per square meter (gsm), and maybe you have another image where you have 4 regions that are all 200 gsm. Is that what you have? In that case, you could average them together. What I was assuming was that you had only one calibration image and that image had serveral regions all representing DIFFERENT pressures. In that case you can't average them together or else you won't have any calibration at all. Other notes: The blue image is image(:,:,3) not image(:,:,2) I don't know of any MATLAB function to have you draw a box. That would be a nice additional utility. Since MATLAB seems to lack that, that's why I wrote my own code where I load up the corners of the box into x and y arrays and call plot(x,y). You can move the boxes by clicking in the image or nudging them with scroll bars. Using RGB2gray does a weighted average of the color channels. However if one channel is no good, like your red channel which has little information in it, then you're averaging in something that will reduce your precision. So obviously you don't want to do that. Averaging will reduce noise (this is a good thing) so if both your green and blue channels look pretty much the same, you can average just those two together to reduce your noise and maintain precision. Often in digital images the blue channel looks pretty noisy. If that is your case, don't use it as it will be worse than using the green channel only. So average the green and blue only if both the signal and the noise look about the same in each channel, otherwise just take the one single best channel, whichever channel that happens to be. Regards, ImageAnalyst
From: ms on 6 May 2008 04:24
On May 5, 5:21 pm, ImageAnalyst <imageanal...(a)mailinator.com> wrote: > On May 5, 2:39 pm, ms <silvert...(a)gmail.com> wrote: > > > > > > > On May 4, 6:57 am, "Image Analyst" <imageanal...(a)mailinator.com> > > wrote: > > > > ms: > > > For each region, you get the mean. You define the regions > > > by whatever means you want. For me, I have a series of > > > boxes where I keep track of topLine, bottomLine, > > > leftColumn, rightColumn for every box. These 4 numbers are > > > put into an array so that I have an N by 2 array where N is > > > the number of calibration regions in the image. Now, you > > > take the mean of each region. If I recall correctly it's > > > something like > > > for k = 1 : numberOfRegions > > > x1 = boxLocations(k).leftColumn; > > > x2 = boxLocations(k).rightColumn ; > > > y1 = boxLocations(k).topLine; > > > y2 = boxLocations(k).bottomLine; > > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > > end > > > I have a GUI that lets people move the boxes around and > > > save their locations, as well as a listbox of calibration > > > images that they can read in. > > > Now you make up two arrays of N by 1. The first array > > > (polyfit's "X" array) is the mean gray levels of the > > > regions, for example 50 gray levels, 100 gray levels and so > > > on. The second array (polyfit's "Y" array) is the actual > > > real world pressures that you used for the region, for > > > example 100 grams/m^2, 200 grams/m^2 and so on. for those > > > regions. > > > actualPressures = [100 200 300 and so on]; > > > Feed these both into polyfit (going by memory here since I > > > don't have MATLAB open at the moment) > > > orderOfPolynomial = 2; > > > coefficients = polyfit(meanOfRegions, actualPressures, > > > orderOfPolynomial); > > > > and you get out an array of coefficients that tell you how > > > to put in a gray level and get out a pressure. Now you're > > > almost done. Next take an image, say the calibration image > > > or any test image with unknown pressures, and get an output > > > image that is the estimated calibrated pressure image. For > > > example > > > estimatedPressures = coefficient(0) + coefficient(1) * > > > testImage + coefficient(2) * (testImage .* testImage); > > > Now you're done and you can go ahead and process that image > > > in any way that you like and you will be working with real > > > world units. > > > These seem like pretty explicit instructions so hopefully > > > they will be enough for you to use, but write back if you > > > still have questions. > > > Best wishes, > > > ImageAnalyst > > > P.S. Pay attention to what I said in the earlier message > > > about getting the monochrome image from the color image > > > (don't do what you said, unless there is no difference in > > > contrast, which I'm pretty sure is not the case, and you're > > > doing it to reduce the noise).- Hide quoted text - > > > You have been extremely helpful! Instead of simply using rgb2gray, I > > tried using image(:,:,2)%this was to look at the blue channel (That is > > correct, right?). I actually looked at 1,2,3 and noticed that the > > blue channel was the best out of the three. Is there any disadvantage > > to this...instead of using rgb2gray (well, that is another story)? > > Back to "selecting the regions". I understand what to do with the > > information once each mean is determined for each of the different > > regions (l think 4 would work in my case)...that is, I would know how > > to use the polyfit function to create my calibration after both > > intesity and pressure are both determined. What I don't understand at > > this point is how you are determining your roi? You sent the code: > > > > for k = 1 : numberOfRegions > > > x1 = boxLocations(k).leftColumn; > > > x2 = boxLocations(k).rightColumn ; > > > y1 = boxLocations(k).topLine; > > > y2 = boxLocations(k).bottomLine; > > > meanOfRegion(k) = mean2(calibrationImage(y1:y2, x1:x2)); > > > end > > > (I would then take mean(meanOfRegion) to give me the overall > > calibration value for this particular image, correct?...I would then > > perform this for each of the other images to be used for calibration.) > > > say numberOfRegions = 4; > > > what are the variables within the loop, such as > > "boxLocations(k).leftColumn"? I am guessing that these are the x,y > > values given by your box used to select a region of interest? I was > > also unfamiliary with the "." seperating the two...is this a > > particular format? > > > I tried using the roipoly function in matlab to select an area, but it > > was somewhat difficult (not an exact box) to use accurately. Is there > > a function that will display a box on the image, move it around, and > > resize the box size (I may be asking too much!)? Or is this type of > > code simple enough to create? > > > Image Analyst, you have been a terrific help. I thought my post was > > going to be ignored or minimal input. I hope I can contribute as you > > have some day!- Hide quoted text - > > > - Show quoted text - > > ---------------------------------------------------------------------------------- > ms: > No, you misunderstand parts of it. The variables in the loop such as > boxLocations(k).leftColumn are the lines and columns defining the > edges of the box. boxLocations is an array so that if you had 4 > boxes, you would have 4 boxLocations's. boxLocations is a "structure" > which means that I can call the fields of the structure virtually > anything I want. Look up "structure" in the help file - it's a type > of variable. Sure, I could have defined an integer array of > boxLocations(4,4) where boxLocations(1,1) would be the left column, > boxLocations(1,2) would be the right column, boxLocations(1,3) would > be the top line, and boxLocations(1,4) would be the bottom line (all > for box #1, and similarly for the other boxes), but I chose to use a > structure instead of an integer array because the structure allows me > to give descriptive names which make the code much more readable. The > dot in between the structure name and it's field is what separates the > structure object from it's fields - same as any other language, it's > pretty standard. > > Now, if I had 4 regions, I certainly would not average them together > like you said except in one very special case: where all your pressure > regions in your image represent the same pressure. For example, you > have one image with 4 regions and all 4 regions represent 100 grams > per square meter (gsm), and maybe you have another image where you > have 4 regions that are all 200 gsm. Is that what you have? In that > case, you could average them together. What I was assuming was that > you had only one calibration image and that image had serveral regions > all representing DIFFERENT pressures. In that case you can't average > them together or else you won't have any calibration at all. > > Other notes: > The blue image is image(:,:,3) not image(:,:,2) > I don't know of any MATLAB function to have you draw a box. That > would be a nice additional utility. Since MATLAB seems to lack that, > that's why I wrote my own code where I load up the corners of the box > into x and y arrays and call plot(x,y). You can move the boxes by > clicking in the image or nudging them with scroll bars. > Using RGB2gray does a weighted average of the color channels. However > if one channel is no good, like your red channel which has little > information in it, then you're averaging in something that will reduce > your precision. So obviously you don't want to do that. Averaging > will reduce noise (this is a good thing) so if both your green and > blue channels look pretty much the same, you can average just those > two together to reduce your noise and maintain precision. Often in > digital images the blue channel looks pretty noisy. If that is your > case, don't use it as it will be worse than using the green channel > only. So average the green and blue only if both the signal and the > noise look about the same in each channel, otherwise just take the one > single best channel, whichever channel that happens to be. > Regards, > ImageAnalyst- Hide quoted text - > > - Show quoted text - Image Analyst, I do have multiple images in which the entire area should be representative of the load applied; however; there is some differences near the edges(slightly lighter than most of the image). The image is a circle that should be representative of the load applied, and I am breaking this up into 4 different parts (like quadrants of a pie), taking the average of each quadrant, then taking the overall average. I would then do this for all 10 different loads. I would then plug all the values to use polyfit and get a calibration curve. The images to be used at a later date will likely have un-uniform patterns and will need to deal with that when that time comes. You were correct, the blue channel (:,:,3) was a noisy channel compared to the green (at least visually to my naked eye...is there a way to quantify this?). As for the structures, it looks like a very nice way to organize data...but will take some getting used to...I only use matrix arrays! I tried averaging the two channels, but kept having problems as they are in uint8 format. So I would have green with an intesity of 180 and blue 200, and when I would add them and divide by 2 the answer would always be 128 (255/2=127.5...I guess it rounds up). gb = ((image(:,:,2)+image(:,:,2))/2). There must be a better way? As for the box...and being able to nudge it and move it...I was unable to do so when I used the plot(x,y) function. I plotted the image (green channel only). created an array for x and y (x=[1 1 10 10 1], y=[1 10 10 1 1]). I then plotted them over the image (plot(x,y)) and a blue box appeared in the upper left corner. I was, however, unable to move the box. Thanks again! |