Saturday, February 4, 2017

Measuring the dimension of an object using OpenCV and Python:BUGS!

BUGS detected!


As you may see from the figure above, rather than detecting the coin as the first object, the program "think" that that "something" on the picture is the coin. Therefore, all the measurement is completely wrong.




Yeah it is horrible. And it turns out that the culprit is that there is an area that is brighter than its surrounding. The bright area is the one that I marked with red circle. Since we are the one who made the "brain" of the program, then we need to re-look at the program.

The most-common culprit, if something is going wrong with your code, is the hard-coded part. So now let us review our code, and find out which part that was hard-coded. Let us start from the highest level, from measure_object_dimension.py. The following line might be troublemaker in the future, since we cannot adjust the measurement unit as well as the diameter manually. Further, we also made a limitation of the filename extension only for .jpg.

1
2
3
if f.lower().endswith('jpg'): images.append(f)

cv.measure_object_dimension(image, coin_diameter = 24, unit = 'mm')

Next, we are going to review the pydonesia.py. Again, we may find a method with pre-defined arguments, such as the following code.

1
2
def measure_object_dimension(self, image, coin_diameter, unit,
                             resize_width=700, rotate_angle=0, blur=(5,5), cannyMin=50, cannyMax=100, edge_iterations=1):

Lastly, we are going to review the last python script, cv_utilities.py, the lowest level of our serial codes. There are some hard-codes all over the methods, however, they are just trivial parameters, such as font size, RGB values, and so forth. Therefore, we are not going to change anything within this cv_utilities.py script.

In summary, here are the parameters that we need to pass manually, not hard-coded them in the program:
  • suffix of the image filename
  • diameter of the coin and its measurement unit (variable coin_diameter and variable unit)
  • width of image after being resized (variable resize_width) for more details: PyImagesearch
  • whether we would like to rotate the image (variable rotate_angle) for more details: PyImagesearch
  • a tuple of Gaussian kernel size (variable blur) for more details: OpenCV
  • the minimum value of Canny Hysteresis Thresholding (variable cannyMin) for more details: OpenCV
  • the maximum value of Canny Hysteresis Thresholding (variable cannyMax) for more details: OpenCV
  • the iterations of morphological transformation (variable edge_iterations) for more details: OpenCV

While I was fixing the code, my friend told me that it is inefficient if she needs to copy and paste the whole program to each folder. She said that it is consuming the storage. So aside from the lists above, we also need to think how to "command" the program to go to the targeted folder that has all the images.

1
2
cwd = os.getcwd()
file_all = os.listdir(cwd)

So we need to improve two lines of the above code taken from measure_object_dimension.py or the highest level of our program.

Since we have already identified the improvement lists, now it is time to work on it! Two ways to fix this, either we make a GUI or keep a .txt file (for example) within the same folder as the main program. The later is easier. However, it is not fancy. Worry not I will get through both ways. But, not in the same post. I will separate the post for each topic.

Frankly speaking I was planning to get through the second way (keep a .txt file within the main program folder). However, due to my regular works, I have to postpone posting it. Sorry for this. I will post the detail codes to fix the bugs next week. So please stay tune! As always, thanks for reading. If you have any comment, query, or anything just leave it in the comment section below. See you next week!

No comments:

Post a Comment