After some processing of a image I, extracted some region of a image.
Here is the .npy file.
segmented_image = np.load('data.npy')
plt.imshow(segmented_image)
Now, I am trying to crop/segment the region of P. How can I do that ?
Thanks in advance.
You can try contour filtration.
import cv2
import numpy as np
image = np.load("data.npy")
cv2.imshow("image", image)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, threshold_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY)
cv2.imshow("threshold_image", threshold_image)
contours, hierarchy = cv2.findContours(threshold_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# here you can apply your conter filter logic
# In this image I can see biggest contur is "p"
selected_contour = max(contours, key=lambda x: cv2.contourArea(x))
mask_image = np.zeros_like(threshold_image)
cv2.drawContours(mask_image, [selected_contour], -1, 255, -1)
cv2.imshow("mask_image", mask_image)
segmented_image = cv2.bitwise_and(image, image, mask=mask_image)
cv2.imshow("segmented_image", segmented_image)
cv2.waitKey(0)
Related
I am newbie to OpenCV. I'm trying to find the contours of the captcha image. It does not work only when my captcha image contains the dotted text.
I have done following code for that:
import numpy as np
import cv2 as cv
import imgaug.augmenters as iaa
im = cv.imread('dataset/1.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
imgray = cv.threshold(imgray, 127, 255, 0)[1]
dst = cv.Canny(imgray,0,150)
blured = cv.blur(dst,(5,5),0)
img_thresh = cv.adaptiveThreshold(blured,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 11, 2)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3,3))
threshed = cv.morphologyEx(img_thresh,cv.MORPH_CLOSE,kernel)
contours, hierarchy = cv.findContours(dst, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print(len(contours))
# cv.drawContours(im, contours, -1, (0, 255, 0), 3)
cv.imshow("img_thresh",img_thresh)
cv.imshow("dst",dst)
cv.imshow("threshed",threshed)
cv.waitKey(0)
cv.destroyAllWindows()
Can anyone help in this? Is there any way to find contours in this image?
Here is my code and output
'''
contours
'''
import numpy as np
import cv2
#read image as gray
pic = r'C:\Users\balaji\Desktop\captcha.jpg'
img_color = cv2.imread(pic)
cv2.imshow('CAPTCHA preview',img_color)
cv2.waitKey(0)
img_gray = cv2.cvtColor(img_color,cv2.COLOR_BGR2GRAY)
#Apply thresholding to the image
ret, thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_OTSU)
cv2.imshow('Thresholded image', thresh)
cv2.waitKey(0)
#Dilated image - to connect the dots
krn = np.ones((3,3), np.uint8)
img_dilated = cv2.dilate(cv2.bitwise_not(thresh), kernel=krn, iterations=1)
cv2.imshow('Dilated image', img_dilated)
cv2.waitKey(0)
# Finding and draw Contours
contours, hierarchy = cv2.findContours(img_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
black_canvas = np.zeros_like(img_color)
cv2.drawContours(black_canvas, contours, -1, (0, 255, 0), 1)
cv2.imshow('Contoured image', black_canvas)
cv2.waitKey(0)
I am new to deep learning and try to implement a ML algorithm for image clustering. The problem is that I can't crop the objects in an image in Python using OpenCV.
Here is the code I have implemented and it works for some objects if the color of the object is very different(in RGB values) from the background but it doesn't work for the image I need for ML algorithm. What kind of parameters should I have/change? Any suggestions?
import cv2
import numpy as np
from PIL import Image
import tkinter as tk
from tkinter import filedialog as fd
from tkinter import*
import random
#!/usr/bin/python
from PIL import Image
import sys
myFile = 'Path' + '/crop.png'
nr_of_im = 1
q = 0
r = 0
x_list = []
y_list = []
img = cv2.imread(myFile, cv2.IMREAD_UNCHANGED)
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 30, 255, cv2.THRESH_BINARY)
contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
print("len",len(contours))
if cv2.contourArea(contour) > 80:
x, y, w, h = cv2.boundingRect(contour)
q = w
r = h
x_list.append(x)
y_list.append(y)
font = cv2.FONT_HERSHEY_SIMPLEX
ROI = img[y-10:y+10+h, x-10:x+10+w]
ROI = cv2.resize(ROI,(300,300))
file_all = "/images/%d.jpg"%nr_of_im
nr_of_im += 1
cv2.imwrite(file_all,ROI)
There are 21 objects in the image but the length of contours returns 1. The image looks like so
crop.png:
Your threshold is too low and produces a totally white image for me. You need to increase your threshold. Always view your thresholding to be sure it is working the way you expect. You can always remove the viewing later.
The following works for me using Otsu thresholding with a threshold value of 97. I get 21 contours.
Input:
import cv2
import numpy as np
# read image
img = cv2.imread('blocks.jpg')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(ret)
# apply morphology fill and separate large regions and remove small ones
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (9,9))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (15,15))
morph = cv2.morphologyEx(morph, cv2.MORPH_OPEN, kernel)
# get contours
result = img.copy()
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
# get count of contours
print(len(contours))
# draw bounding boxes on contours
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2)
#print("x,y,w,h:",x,y,w,h)
# save results
cv2.imwrite("blocks_thresh.jpg", thresh)
cv2.imwrite("blocks_morphology.jpg", morph)
cv2.imwrite("blocks_bboxes.jpg", result)
# show thresh and result
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Threshold image:
Morphology cleaned image:
Resulting bounding boxes from contours:
I have my code like this:
import numpy as np
import cv2
im = cv2.imread('snorlax.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
cv2.drawContours(im, contours, -1, (0, 255, 0), 3)
cv2.imshow("imagen", im)
input()
The print show a list of lists that have to number every list I dont know if that are the points (x,y) of the contours and the cv2.show only showme a grey screen and doesn't show me the contours of the image.
import numpy as np
import cv2
img = cv2.imread("snorlax.jpg", cv2.IMREAD_GRAYSCALE)
canny = cv2.Canny(img, 100, 150)
cv2.imshow("Image", img)
cv2.imshow("Canny", canny)
indices = np.where(canny != [0])
coordinates = zip(indices[0], indices[1])
coordinates_list = ""
for coordinate in coordinates:
x = "'('{}, {}')', ".format(coordinate[1] / 100, -coordinate[0] / 100)
coordinates_list += x
coordinates_list = "'('{}')'".format(coordinates_list)
coordinates_list = coordinates_list.replace("'('", "{")
coordinates_list = coordinates_list.replace("')'", "}")
print(coordinates_list)
cv2.waitKey(0)
cv2.destroyAllWindows()
I use canny to resolve the problem then with the "where" function of numpy I get all the white points and zip it in a variable, the last past of the code is to get the points in a specific format to use it in an other language.
I have an image that is blurred and contains some noise. I have tried Image Denoising from the following example.
The code to remove the Gaussian noise from a color image using the Non-local Means Denoising algorithm:
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread("data_5/1.png")
b,g,r = cv2.split(img) # get b,g,r
rgb_img = cv2.merge([r,g,b]) # switch it to rgb
# Denoising
dst = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
b,g,r = cv2.split(dst) # get b,g,r
rgb_dst = cv2.merge([r,g,b]) # switch it to rgb
cv2.imshow('denoising black and white', rgb_dst)
cv2.waitKey(0)
The output of the above code:
The above code removes some noise. But here some numbers are blurred and the table lines are blurred.
Can anyone suggest me a better solution to remove blurriness and Noise from the above image?
import numpy as np
import cv2
from PIL import Image
from tesserocr import PyTessBaseAPI, RIL
if __name__ == '__main__':
image = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
image = cv2.resize(image, (0,0), fx=0.5, fy=0.5)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
binary = cv2.medianBlur(binary, 3)
(rows,cols) = image.shape[:2]
H = cv2.Sobel(binary, cv2.CV_8U, 1, 0, ksize = 5)
V = cv2.Sobel(binary, cv2.CV_8U, 0, 1, ksize = 5)
_,contours,_ = cv2.findContours(V, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
(x,y,w,h) = cv2.boundingRect(cnt)
if w < cols/3 and h < rows/3:
cv2.drawContours(V, [cnt], -1, 0, -1)
_,contours,_ = cv2.findContours(H, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
(x,y,w,h) = cv2.boundingRect(cnt)
if w < cols/3 and h < rows/3:
cv2.drawContours(H, [cnt], -1, 0, -1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
V = cv2.morphologyEx(V, cv2.MORPH_DILATE, kernel, iterations = 3)
H = cv2.morphologyEx(H, cv2.MORPH_DILATE, kernel, iterations = 3)
binary[V == 255] = 0
binary[H == 255] = 0
binary = cv2.bitwise_not(binary)
api = PyTessBaseAPI()
api.SetImage(Image.fromarray(binary))
text = api.GetUTF8Text()
text = text.split()
boxes = api.GetComponentImages(RIL.TEXTLINE, True)
for i, (_, box, _, _) in enumerate(boxes):
(x,y,w,h) = box['x'], box['y'], box['w'], box['h']
cv2.rectangle(image, (x,y), (x+w,y+h), (0,0,255))
cv2.putText(image, text[i], (x,y), cv2.FONT_HERSHEY_PLAIN, 1, (255,0,0))
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
I have tried applying a Gaussian Blur then processing it with adaptive thresholding and result removed noise in the image and blurriness.
import cv2 as cv
#input
img = cv.imread('data_5/1.png',0)
#gaussian Blur
img = cv.GaussianBlur(img, (15,15),0)
#adaptive threshold
th3 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv.THRESH_BINARY,11,2)
cv2.imshow('Noise Filtered Image', th3)
cv2.waitKey(0)
cv.imwrite('data_5/result.png',th3)
The output of the above code:
Can anyone help me to smoothen this image? I want an output quality similar to this table below. Removal of table lines is ok.
My goal is to have an image with clear text.
I have an image such as this
I am trying to detect and remove the arrow from this image so that I end up with an image that just has the text.
I tried the below approach but it isn't working
image_src = cv2.imread("roi.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
canny=cv2.Canny(gray,50,200,3)
ret, gray = cv2.threshold(canny, 10, 255, 0)
contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
largest_area = sorted(contours, key=cv2.contourArea)[-1]
mask = np.ones(image_src.shape[:2], dtype="uint8") * 255
cv2.drawContours(mask, [largest_area], -1, 0, -1)
image = cv2.bitwise_and(image_src, image_src, mask=mask)
The above code seems to give me back the same image WITH the arrow.
How can I remove the arrow?
The following will remove the largest contour:
import numpy as np
import cv2
image_src = cv2.imread("roi.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(gray, 250, 255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
mask = np.zeros(image_src.shape, np.uint8)
largest_areas = sorted(contours, key=cv2.contourArea)
cv2.drawContours(mask, [largest_areas[-2]], 0, (255,255,255,255), -1)
removed = cv2.add(image_src, mask)
cv2.imwrite("removed.png", removed)
Note, the largest contour in this case will be the whole image, so it is actually the second largest contour.