Skip to content

Commit 4c78b87

Browse files
Update README.md
1 parent d21ce0a commit 4c78b87

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed

README.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,228 @@ In specifying the range , we have specified the range of blue color. Whereas you
173173
That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise.
174174

175175
When the lower and/or upper boundary parameters are scalars, the indexes (I) at lowerb and upperb in the above formulas should be omitted.
176+
177+
## 8. res = cv2.bitwise_and( frame2, frame2, mask = mask)
178+
179+
**Bitwise Operations**
180+
181+
This includes bitwise AND, OR, NOT and XOR operations. They will be highly useful while extracting any part of the image (as we will see in coming chapters), defining and working with non-rectangular ROI etc. Below we will see an example on how to change a particular region of an image.
182+
183+
```
184+
import cv2
185+
186+
## Read
187+
img = cv2.imread("sunflower.jpg")
188+
189+
## convert to hsv
190+
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
191+
192+
## mask of green (36,0,0) ~ (70, 255,255)
193+
mask1 = cv2.inRange(hsv, (36, 0, 0), (70, 255,255))
194+
195+
## mask o yellow (15,0,0) ~ (36, 255, 255)
196+
mask2 = cv2.inRange(hsv, (15,0,0), (36, 255, 255))
197+
198+
## final mask and masked
199+
mask = cv2.bitwise_or(mask1, mask2)
200+
target = cv2.bitwise_and(img,img, mask=mask)
201+
202+
cv2.imwrite("target.png", target)
203+
```
204+
This code above using bitwise_or and bitwise_and.
205+
206+
<p align="center">
207+
<img src="https://i.stack.imgur.com/CMEaA.jpg">
208+
</p>
209+
210+
Find green and yellow(the range is not that accurate):
211+
212+
<p align="center">
213+
<img src="https://i.stack.imgur.com/8ydJj.png">
214+
</p>
215+
216+
---
217+
218+
## 9. kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10))
219+
220+
In some cases, you may need elliptical/circular shaped kernels. So for this purpose, OpenCV has a function, cv2.getStructuringElement(). You just pass the shape and size of the kernel, you get the desired kernel.
221+
222+
```
223+
# Rectangular Kernel
224+
>>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
225+
array([[1, 1, 1, 1, 1],
226+
[1, 1, 1, 1, 1],
227+
[1, 1, 1, 1, 1],
228+
[1, 1, 1, 1, 1],
229+
[1, 1, 1, 1, 1]], dtype=uint8)
230+
231+
# Elliptical Kernel
232+
>>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
233+
array([[0, 0, 1, 0, 0],
234+
[1, 1, 1, 1, 1],
235+
[1, 1, 1, 1, 1],
236+
[1, 1, 1, 1, 1],
237+
[0, 0, 1, 0, 0]], dtype=uint8)
238+
239+
# Cross-shaped Kernel
240+
>>> cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
241+
array([[0, 0, 1, 0, 0],
242+
[0, 0, 1, 0, 0],
243+
[1, 1, 1, 1, 1],
244+
[0, 0, 1, 0, 0],
245+
[0, 0, 1, 0, 0]], dtype=uint8)
246+
```
247+
---
248+
249+
## 10. opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
250+
251+
# Morphological Transformations
252+
253+
**Theory**
254+
255+
* Morphological transformations are some simple operations based on the image shape.
256+
* It is normally performed on binary images.
257+
* It needs two inputs, one is our original image, second one is called structuring element or kernel which decides the nature of operation.
258+
* Two basic morphological operators are Erosion and Dilation. Then its variant forms like Opening, Closing, Gradient etc also comes into play.
259+
260+
We will see them one-by-one with help of following image:
261+
262+
<p align="center">
263+
<img src="https://docs.opencv.org/3.0-beta/_images/j.png">
264+
</p>
265+
266+
1. **Erosion**
267+
268+
The basic idea of erosion is just like soil erosion only, it erodes away the boundaries of foreground object (Always try to keep foreground in white). So what it does? The kernel slides through the image (as in 2D convolution). A pixel in the original image (either 1 or 0) will be considered 1 only if all the pixels under the kernel is 1, otherwise it is eroded (made to zero).
269+
270+
So what happends is that, all the pixels near boundary will be discarded depending upon the size of kernel. So the thickness or size of the foreground object decreases or simply white region decreases in the image. It is useful for removing small white noises detach two connected objects etc.
271+
272+
Here, as an example, I would use a 5x5 kernel with full of ones. Let’s see it how it works:
273+
```
274+
import cv2
275+
import numpy as np
276+
277+
img = cv2.imread('j.png',0)
278+
kernel = np.ones((5,5),np.uint8)
279+
erosion = cv2.erode(img,kernel,iterations = 1)
280+
```
281+
Result:
282+
283+
<p align="center">
284+
<img src="https://docs.opencv.org/3.0-beta/_images/erosion.png">
285+
</p>
286+
287+
2. **Dilation**
288+
289+
It is just opposite of erosion. Here, a pixel element is ‘1’ if atleast one pixel under the kernel is ‘1’. So it increases the white region in the image or size of foreground object increases. Normally, in cases like noise removal, erosion is followed by dilation. Because, erosion removes white noises, but it also shrinks our object. So we dilate it. Since noise is gone, they won’t come back, but our object area increases. It is also useful in joining broken parts of an object.
290+
291+
```dilation = cv2.dilate(img,kernel,iterations = 1)```
292+
293+
Result:
294+
295+
<p align="center">
296+
<img src="https://docs.opencv.org/3.0-beta/_images/dilation.png">
297+
</p>
298+
299+
3. **Opening**
300+
301+
Opening is just another name of erosion followed by dilation. It is useful in removing noise, as we explained above. Here we use the function, cv2.morphologyEx()
302+
303+
```opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)```
304+
305+
Result:
306+
307+
<p align="center">
308+
<img src="https://docs.opencv.org/3.0-beta/_images/opening.png">
309+
</p>
310+
311+
4. **Closing**
312+
Closing is reverse of Opening, Dilation followed by Erosion. It is useful in closing small holes inside the foreground objects, or small black points on the object.
313+
314+
```closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)```
315+
316+
Result:
317+
318+
<p align="center">
319+
<img src="https://docs.opencv.org/3.0-beta/_images/opening.png">
320+
</p>
321+
322+
5. **Morphological Gradient**
323+
324+
It is the difference between dilation and erosion of an image.
325+
326+
The result will look like the outline of the object.
327+
328+
```gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)```
329+
330+
Result:
331+
<p align="center">
332+
<img src="https://docs.opencv.org/3.0-beta/_images/gradient.png">
333+
</p>
334+
335+
336+
## 11. center = (int(moment['m10']/moment['m00']), int(moment['m01']/moment['m00']))
337+
338+
339+
Moments
340+
===========
341+
342+
One of the simplest ways to compare two contours is to compute contour moments.
343+
344+
This is a good time for a short digression into precisely what a moment is. Loosely speaking, a moment is a gross characteristic of the contour computed by integrating (or summing, if you like) over all of the pixels of the contour. In general, we defi ne the (p, q) moment of a contour as
345+
346+
<p align="center">
347+
<img src="https://github.com/varshneydevansh/object-detect-opencv/blob/master/opencv.png">
348+
</p>
349+
350+
Image moments help you to calculate some features like center of mass of the object, area of the object etc. Check out the wikipedia page on `Image Moments <http://en.wikipedia.org/wiki/Image_moment>`_
351+
352+
The function **cv2.moments()** gives a dictionary of all moment values calculated. See below:
353+
::
354+
355+
import cv2
356+
import numpy as np
357+
358+
img = cv2.imread('star.jpg',0)
359+
ret,thresh = cv2.threshold(img,127,255,0)
360+
contours,hierarchy = cv2.findContours(thresh, 1, 2)
361+
362+
cnt = contours[0]
363+
M = cv2.moments(cnt)
364+
print M
365+
366+
From this moments, you can extract useful data like area, centroid etc. Centroid is given by the relations, .
367+
368+
This can be done as follows:
369+
::
370+
371+
cx = int(M['m10']/M['m00'])
372+
cy = int(M['m01']/M['m00'])
373+
374+
375+
376+
377+
378+
379+
380+
381+
382+
383+
384+
385+
386+
387+
388+
389+
390+
391+
392+
393+
394+
395+
396+
397+
176398

177399

178400

0 commit comments

Comments
 (0)