I would like to divide image based on the bounding boxes. Image consist of column name and row, but column don't have any border so depends on gap it should divide
I am able to identify the bounding box, I am not understanding on what bases image should be cropped
large = cv2.imread("../forms/demo_1/crop/abc.jpg")
rgb = large
small = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
grad = cv2.morphologyEx(small, cv2.MORPH_GRADIENT, kernel)
_, bw = cv2.threshold(grad, 0.0, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 1))
connected = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel)
contours, hierarchy = cv2.findContours(connected.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
mask = np.zeros(bw.shape, dtype=np.uint8)
for idx in range(len(contours)):
x, y, w, h = cv2.boundingRect(contours[idx])
mask[y:y+h, x:x+w] = 0
cv2.drawContours(mask, contours, idx, (255, 255, 255), -1)
r = float(cv2.countNonZero(mask[y:y+h, x:x+w])) / (w * h)
if r > 0.4 and w > 3 and h > 8:
cv2.rectangle(rgb, (x, y), (x+w-1, y+h-1), (0, 255, 0), 2)
print(x,y,x+w,y+h)
cv2.imshow('rects', rgb)
cv2.waitKey()
cv2.destroyAllWindows()
Input:
Output:
This is how you crop a rectangle from an image in OpenCV (see also this tutorial):
import cv2
large = cv2.imread("../forms/demo_1/crop/abc.jpg")
# ... your code
for idx in range(len(contours)):
# ... your code to calculate x, y, w, g
# example values. Use your calculated values here
x, y, w, h = 0, 0, 60, 250
crop = large[x:x+w, y:y+h]
cv2.imshow('crop', crop)
cv2.waitKey()
Related
I tried to mask image by its color using opencv.
import cv2
import numpy as np
import matplotlib.pyplot as plt
After importing libraries, I load the image
img = cv2.imread('gmaps.jpg')
image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(image);
Turn the color into hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
plt.imshow(hsv);
Masking process
low_orange = np.array([44, 6, 100])
high_orange = np.array([44, 24, 99])
masking = cv2.inRange(hsv,low_orange, high_orange)
plt.imshow(masking);
The result isn't what I expected.
Image :
Result :
EDIT: I want to mask the building only. Instead I got the result of masking all of the frame.
Using my answer from here I manage to extract the right values for you
Code:
frame = cv2.imread("Xv6gx.png")
blurred_frame = cv2.GaussianBlur(frame, (5, 5), 0)
hsv = cv2.cvtColor(blurred_frame, cv2.COLOR_BGR2HSV)
lower = np.array([4, 0, 7])
upper = np.array([87, 240, 255])
mask = cv2.inRange(hsv, lower, upper)
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for contour in contours:
area = cv2.contourArea(contour)
if area > 5000:
# -- Draw Option 1 --
cv2.drawContours(frame, contour, -1, (0, 255, 0), 3)
# -- Draw Option 2--
# rect = cv2.boundingRect(contour)
# x, y, w, h = rect
# cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Mask", mask)
cv2.imshow("Frame", frame)
cv2.waitKey(0)
Final Results:
I wouldn't expect the low Value (100) to exceed the high Value (99).
Also, OpenCV uses a range of 0..180 for Hue rather than 0..360, so you likely need to divide your 44 by 2.
I am new to StackOverflow.
I am trying to detecting shapes as per names and shapes in image of diamonds.various shapes of diamond. For shape detection purpose I used the program given at https://www.pyimagesearch.com/2016/02/08/opencv-shape-detection/
Here is the code:
import cv2
import imutils
class ShapeDetector:
def __init__(self):
pass
def detect(self, c):
# initialize the shape name and approximate the contour
shape = "unidentified"
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
# if the shape is a triangle, it will have 3 vertices
if len(approx) == 3:
shape = "triangle"
# if the shape has 4 vertices, it is either a square or
# a rectangle
elif len(approx) == 4:
# compute the bounding box of the contour and use the
# bounding box to compute the aspect ratio
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
# a square will have an aspect ratio that is approximately
# equal to one, otherwise, the shape is a rectangle
shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
# if the shape is a pentagon, it will have 5 vertices
elif len(approx) == 5:
shape = "pentagon"
# otherwise, we assume the shape is a circle
else:
shape = "circle"
# return the name of the shape
return shape
# -----------------
image = cv2.imread(shape_image)
resized = imutils.resize(image, width=300)
ratio = image.shape[0] / float(resized.shape[0])
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 20, 255, cv2.THRESH_BINARY)[1]
# find contours in the thresholded image and initialize the
# shape detector
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
sd = ShapeDetector()
# loop over the contours
for c in cnts:
# compute the center of the contour, then detect the name of the
# shape using only the contour
M = cv2.moments(c)
cX = int((M["m10"] / M["m00"]) * ratio)
cY = int((M["m01"] / M["m00"]) * ratio)
shape = sd.detect(c)
# multiply the contour (x, y)-coordinates by the resize ratio,
# then draw the contours and the name of the shape on the image
c = c.astype("float")
c *= ratio
c = c.astype("int")
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
print("The Shape of Object is: ", shape)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
But, I am unable to get perfect results for that. Is there any way to find out shapes like which are given in image.
I am trying to predict rectangular boxes around the line of the text in a document image.For this I am using semantic segmentation.After getting rectangular boxes I want to resize them in such a way that it fits into original image.For doing prediction I am resizing them to 500 x 500 size.
def draw_boxes(filename):
img=cv2.imread(f'{filename}',0)
ret,img=cv2.threshold(img,150,255,cv2.THRESH_BINARY_INV)
img=cv2.resize(img,(512,512))
img= np.expand_dims(img,axis=-1)
img=np.expand_dims(img,axis=0)
pred=model.predict(img)
pred=np.squeeze(np.squeeze(pred,axis=0),axis=-1)
plt.imsave('test_img_mask.JPG',pred)
coordinates=[]
img = cv2.imread('test_img_mask.JPG',0)
cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU,img)
ori_img=cv2.imread(f'{filename}')
ori_img=cv2.resize(ori_img,(512,512))
contours, hier = cv2.findContours(img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for c in contours:
# get the bounding rect
x, y, w, h = cv2.boundingRect(c)
# draw a white rectangle to visualize the bounding rect
cv2.rectangle(ori_img, (x, y), (x+w,y+h), 255, 1)
coordinates.append([x,y,(x+w),(y+h)])
cv2.imwrite("output.jpg",ori_img)
Well I found the solution to the above problem.It can be done by obtaining the rescaling factor=Original_image_size/512(in my case) and then multiple with my coordinates.
def draw_boxes(filename):
img=cv2.imread(f'{filename}',0)
ret,img=cv2.threshold(img,150,255,cv2.THRESH_BINARY_INV)
img=cv2.resize(img,(512,512))
img= np.expand_dims(img,axis=-1)
img=np.expand_dims(img,axis=0)
pred=model.predict(img)
pred=np.squeeze(np.squeeze(pred,axis=0),axis=-1)
plt.imsave('test_img_mask.JPG',pred)
coordinates=[]
img = cv2.imread('test_img_mask.JPG',0)
cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU,img)
ori_img=cv2.imread(f'{filename}')
(H, W) = ori_img.shape[:2]
(newW, newH) = (512, 512)
rW = W / float(newW)
rH = H / float(newH)
contours, hier = cv2.findContours(img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for c in contours:
# get the bounding rect
x, y, w, h = cv2.boundingRect(c)
# draw a white rectangle to visualize the bounding rect
cv2.rectangle(ori_img, (int(x*rW),int(y*rH)), (int((x+w)*rW),int((y+h)*rH)), (255,0,0), 1)
cv2.imwrite("output.jpg",ori_img)
I am trying to measure the size and count of bubbles available in image taken from real world material particles.
I have tried the approach present Here (second one with opencv). But some how it doesnt work probably because of the bubbles, because image is kind of an average quality.
Can some one please direct me to correct direction or provide recommendation?
The reference image, i am trying process is
Result:
It doesn't detects the circles, in fact at finding contours step, it gets a zero therefore the test is not passed.
Made some changes. Able to detect some bubbles but still not good. Detected bubble image is below
Thanks
Code:
import cv2
image = cv2.imread('....')
# Gray, blur, adaptive threshold
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (11,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Morphological transformations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# Find contours
cnts = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
# Find perimeter of contour
perimeter = cv2.arcLength(c, True)
# Perform contour approximation
approx = cv2.approxPolyDP(c, 0.04 * perimeter, True)
if len(approx) > 6:
# Obtain bounding rectangle to get measurements
x,y,w,h = cv2.boundingRect(c)
# Find measurements
diameter = w
radius = w/2
# Find centroid
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# Draw the contour and center of the shape on the image
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),4)
cv2.drawContours(image,[c], 0, (36,255,12), 4)
cv2.circle(image, (cX, cY), 15, (320, 159, 22), -1)
# Draw line and diameter information
cv2.line(image, (x, y + int(h/2)), (x + w, y + int(h/2)), (156, 188, 24), 3)
cv2.putText(image, "Diameter: {}".format(diameter), (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 3, (156, 188, 24), 3)
cv2.imwrite('...', image)
cv2.imwrite('...', thresh)
cv2.imwrite('...', opening)
I want to detect paper sheet from image. i applied medianBlur, Canny , dilate, threshold, etc. algorithms to find.i am able to find sheet but don't know how to crop rectangle and apply transformation
answer sheet
This my code
import numpy as np
import cv2
image = cv2.imread('im_1.jpg')
image = cv2.resize(image, (800, 600))
draw = np.zeros_like(image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
thresh = cv2.erode(thresh, kernel, iterations=4)
thresh = cv2.dilate(thresh, kernel, iterations=4)
im, cnts, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
max_area = -1
max_c = 0
for i in range(len(cnts)):
contour = cnts[i]
area = cv2.contourArea(contour)
if (area > max_area):
max_area = area
max_c = i
contour = cnts[max_c]
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box],-1, (0, 255, 0), 2)
cv2.imshow('Sheet', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
result of code:
result
There are some minor flaws in your approach. The following code will help. I have mentioned the changes made as well.
Code:
import numpy as np
import cv2
image = cv2.imread('C:/Users/Jackson/Desktop/score.jpg')
#--- Resized the image to half its dimension maintaining the aspect ratio ---
image = cv2.resize(image, (0, 0), fx = 0.5, fy = 0.5)
draw = np.zeros_like(image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#--- I found the inverse binary image, because contours are found for objects in white. Since the border of the page is in black you have to invert the binary image. This is where it went wrong.
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
#--- I did not perform any morphological operation ---
im, cnts, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
max_area = -1
max_c = 0
for i in range(len(cnts)):
contour = cnts[i]
area = cv2.contourArea(contour)
if (area > max_area):
max_area = area
max_c = i
contour = cnts[max_c]
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box],-1, (0, 255, 0), 2)
cv2.imshow('Sheet', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result: