Cropping rectangle from Image using Opencv python - python

Im trying to crop rectangle image from screenshot, background for image must be white, Im ending up having black,How can I change that? I want to make histogtam of rgb for the final image and It seems plotting only vertical line on zero, Any kind of help is very important! here is my code:
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
image = cv2.imread(filename = "Screenshot from 2019-11-08 22-02-27.png")
mask = np.zeros(shape = image.shape, dtype = "uint8")
cv2.rectangle(img = mask,
pt1 = (0, 185), pt2 = (1900, 773),
color = (255, 255, 255),
thickness = -1)
maskedImg = cv2.bitwise_and(src1 = image, src2 = mask)
cv2.imwrite("processed.png", maskedImg)
plt.imshow(maskedImg)
plt.show()
plt.hist(maskedImg.ravel(),256,[0,256]); plt.show()

import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
image = cv2.imread(filename = "1.png")
mask = np.zeros(shape = image.shape, dtype = "uint8")
cv2.rectangle(img = mask,
pt1 = (0, 185), pt2 = (1900, 773),
color = (255, 255, 255),
thickness = -1)
maskedImg = cv2.bitwise_and(src1 = image, src2 = mask)
maskedImg[np.where((maskedImg==[0,0,0]).all(axis=2))] = [255,255,255]
cv2.imwrite("processed.png", maskedImg)
plt.imshow(maskedImg)
plt.show()
Convert the black pixel present in the image into white pixel
Original image
Crop Image
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([maskedImg],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()

Related

Make img's close range of RGB/HSV in particular value

share pic link: https://imgur.com/a/yyQChWQ
If I have black gradient img , we know the RGB is (0 ~ 255) or HSV is (0 ~ 255)
How can I make close color range color together
such as ( 0 ~ 80), ( 80 ~ 160) , ( 160 ~ 255)
expect output:
1. I want the output to be (expect pic in link) (to remove noise)
2. generate histogram for (original pic) in 1D not 3D that too complicate I can't understand
here is the .py script can show HSV and RGB of pic, I saved the result in share pic link
import numpy as np
import cv2
import matplotlib.pyplot as plt
def show_img(path):
img = cv2.imread(path)
b, g, r = img[:,:,0], img[:,:,1], img[:,:,2]
hist_b = cv2.calcHist([b],[0],None,[256],[0,256])
hist_g = cv2.calcHist([g],[0],None,[256],[0,256])
hist_r = cv2.calcHist([r],[0],None,[256],[0,256])
plt.plot(hist_r, color='r', label="r")
plt.plot(hist_g, color='g', label="g")
plt.plot(hist_b, color='b', label="b")
plt.legend()
plt.show()
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = img2[:,:,0], img2[:,:,1], img2[:,:,2]
hist_h = cv2.calcHist([h],[0],None,[256],[0,256])
hist_s = cv2.calcHist([s],[0],None,[256],[0,256])
hist_v = cv2.calcHist([v],[0],None,[256],[0,256])
plt.plot(hist_h, color='r', label="h")
plt.plot(hist_s, color='g', label="s")
plt.plot(hist_v, color='b', label="v")
plt.legend()
plt.show()
return hist_r,hist_g, hist_b, hist_h, hist_s, hist_v
aaa = "/home/student_DC/desktop/optimization_11_10/output_11_10__002/22.png"
r,g,b,h,s,v = show_img(aaa)
My suggestion is to use a grayscale image so that all the computations and displays are easier:
import numpy as np
import cv2
import matplotlib.pyplot as plt
path = "**/RKqsXEv.png"
# Read the image in grayscale
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
img_filtered = img.copy()
# Simple editing through a loop on pixels value
for i in range (img.shape[0]):
for j in range(img.shape[1]):
if (img[i,j] < 80):
img_filtered[i,j] = 40
elif (img[i,j] < 160):
img_filtered[i,j] = 120
else:
img_filtered[i,j] = 200
plt.imshow(img_filtered, cmap='gray')
plt.show()
# Calculate a 1D histogram on the grayscale image
hist = cv2.calcHist(img, [0], None, [255], [0,255])
plt.plot(hist)
plt.show()
Output:

Why cv2.VideoWriter in python changes the defined color

In the code below I defined the color of the rectangle as fc='#fff300' which the RGB is (255,163,0). Therefore, all the frames of the video should have the above color, but the RGB of the video is (36,255,219) which is totally another color.
I am wondering how to keep the color of the rectangle for the video as well?
import matplotlib.pyplot as plt
import numpy as np
from cv2 import VideoWriter, VideoWriter_fourcc
pixels = 600
my_dpi = 100
FPS=1
for i in range(5):
fig = plt.figure(5,figsize=( pixels/my_dpi, pixels/my_dpi),facecolor='k', dpi=my_dpi)
plt.axes([0,0,1,1])
rectangle = plt.Rectangle((-300, -300), 600, 600, fc='#fff300')
plt.gca().add_patch(rectangle)
plt.savefig('1.png',dpi=my_dpi)
plt.show()
fig.canvas.draw() # draw the figure
data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8) # save it to a numpy array.
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
fourcc = VideoWriter_fourcc(*'MP42')
video = VideoWriter(('1.mp4'), fourcc, FPS, (pixels, pixels))
video.write(data)
video.release()

How to invert axis of a pillow image

Seaborn offers the possibility to invert the axis of an image. I would like to do the same with PIL. Here is my code.
# Imports
import seaborn as sns; sns.set_theme()
import matplotlib.pyplot as plt
import numpy as np
import numpy as np; np.random.seed(0)
from PIL import Image
import random
# Arrays
r = []
g = []
b = []
for i in range(200):
r.append(random.sample(range(0, 255), 200))
g.append(random.sample(range(0, 255), 200))
b.append(random.sample(range(0, 255), 200))
# Change color of the left part of the image
r = np.array(r)
r[:, 0:10]=0
# Change color of the right part of the image
r = np.array(r)
r[:, -10:-1]=150
g = np.array(g)
g[:, -10:-1]=150
# Plot seaborn heatmap
fig, ax = plt.subplots()
sax = sns.heatmap(r)
sax.invert_xaxis()
sax.invert_xaxis() inverts the x-axis of the plot.
I would like to do the same with pillow. I have been google it for a long time without finding anything.
Here is my rgb pillow image.
rgbarr = np.zeros((200,200,3), 'uint8')
rgbarr[..., 0] = np.array(r)
rgbarr[..., 1] = np.array(g)
rgbarr[..., 2] = np.array(b)
img = Image.fromarray(rgbarr)
img
opencv possibility would also be welcome.
I think you just want to flip it:
im_flipped = im.transpose(method=Image.FLIP_LEFT_RIGHT)

opencv - plot contours in an image

I am trying to draw contour around an image. I can see that contours being found but I am not able to draw the outline. The color of the contour seem to be either of the two (black and white) colors.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage import io
%matplotlib inline
im = io.imread('http://matlabtricks.com/images/post-35/man.png')
plt.imshow(im)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
plt.figure()
plt.imshow(imgray)
#Contoured image
ret,thresh = cv2.threshold(imgray, 120,255,cv2.THRESH_BINARY)
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c_img = cv2.drawContours(image, contours, -1, (0, 255, 0), 1)
plt.figure()
plt.imshow(c_img)
You need to draw on the original image, not on the one returned from findContuors(). The following works.
# Contoured image
ret,thresh = cv2.threshold(imgray, 120,255,cv2.THRESH_BINARY)
contours = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[-2]
for contour in contours:
cv2.drawContours(im, contour, -1, (0, 255, 0), 3)
plt.figure()
plt.imshow(im)
This is my result:
## Read and convert
img = io.imread('http://matlabtricks.com/images/post-35/man.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
## Find outer contours
_, cnts, _= cv2.findContours(gray,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
## Draw
canvas = np.zeros_like(img)
cv2.drawContours(canvas , contours, -1, (0, 255, 0), 1)
plt.imshow(canvas)

How to change the thickness of the edge (contour) of an Image?

I am trying to extract the edge of an image (its contour) and change its thickness. I want to give it like the stroke effect of Photoshop layer style. Photoshop stroke effect example:
http://projectwoman.com/2012/11/smart-objects-and-strokes-in-photoshop.html
I was able to extract the edge from an image. Using canny edge or the pillow function.
1.using canny edge detection
img = cv2.imread(img_path,0)
edges = cv2.Canny(img,300,700)
2.using pillow filler
image = Image.open(img_path).convert('RGB')
image = image.filter(ImageFilter.FIND_EDGES())
but, I could not adjust the contour thickness.
Here a solution:
import cv2
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread('mickey.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB)[...,0]
def show_img(im, figsize=None, ax=None, alpha=None):
if not ax: fig,ax = plt.subplots(figsize=figsize)
ax.imshow(im, alpha=alpha)
ax.set_axis_off()
return ax
def getBordered(image, width):
bg = np.zeros(image.shape)
_, contours, _ = cv2.findContours(image.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
biggest = 0
bigcontour = None
for contour in contours:
area = cv2.contourArea(contour)
if area > biggest:
biggest = area
bigcontour = contour
return cv2.drawContours(bg, [bigcontour], 0, (255, 255, 255), width).astype(bool)
im2 = getBordered(image, 10)
show_img(im2, figsize=(10,10))
You can change thickness by changing param width in getBordered.

Categories

Resources