I am drawing a blue rectangle in framebuffer, and I want to erase it again. Before I draw the rectangle I copy the background where the rectangle will be pasted, and paste it over the rectangle after 2 seconds. The rectangle is not erased.
#!/usr/bin/env python
import numpy as np
import time
from PIL import Image
from io import BytesIO
h, w, c = 1024, 1280, 4
fb = np.memmap('/dev/fb0', dtype='uint8',mode='w+', shape=(h,w,c))
x0, y0 = 50, 200
w, h = 300, 400
# Copy backbround: Does not work?
n0 = fb.read[y0:y0+h, x0:x0+w]
# Paste blue rectangle to framebuffer: This works.
img = Image.new('RGBA', size=(w, h), color=(255,0,0,255))
n = np.array(img)
fb[y0:y0+h, x0:x0+w] = n
# Erase image: Does not work?
time.sleep(2)
fb[y0:y0+h, x0:x0+w] = n0
What am I doing wrong?
If I paste n0 to another place in framebuffer, I get a blue rectangle, not a black one.
I solved it myself by using np.copy:
import numpy as np
import time
from PIL import Image
h, w, c = 1024, 1280, 4
fb = np.memmap('/dev/fb0', dtype='uint8',mode='w+', shape=(h,w,c))
x0, y0 = 50, 200
w, h = 300, 400
# Copy background:
### n0 = fb.read[y0:y0+h, x0:x0+w]
n0 = np.copy(fb[y0:y0+h, x0:x0+w])
# Paste blue rectangle to framebuffer: This works.
img = Image.new('RGBA', size=(w, h), color=(255,0,0,255))
n = np.array(img)
fb[y0:y0+h, x0:x0+w] = n
# Erase image:
time.sleep(2)
### fb[y0:y0+h, x0:x0+w] = n0
fb[y0:y0+h, x0:x0+w] = np.copy(n0)
Related
This is the image I need to deskew
I don't want to run object detection here,
I tried the following script, but that didn't work
what should I do next ?
import math
from typing import Tuple, Union
import cv2
import numpy as np
from deskew import determine_skew
def rotate(
image: np.ndarray, angle: float, background: Union[int, Tuple[int, int, int]]
) -> np.ndarray:
old_width, old_height = image.shape[:2]
angle_radian = math.radians(angle)
width = abs(np.sin(angle_radian) * old_height) + abs(np.cos(angle_radian) * old_width)
height = abs(np.sin(angle_radian) * old_width) + abs(np.cos(angle_radian) * old_height)
image_center = tuple(np.array(image.shape[1::-1]) / 2)
rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
rot_mat[1, 2] += (width - old_width) / 2
rot_mat[0, 2] += (height - old_height) / 2
return cv2.warpAffine(image, rot_mat, (int(round(height)), int(round(width))), borderValue=background)
image = cv2.imread('/content/img.jpg')
grayscale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
angle = determine_skew(grayscale)
rotated = rotate(image
, angle, (0, 0, 1))
cv2_imshow(rotated)
and this simpler version too
import numpy as np
from skimage import io
from skimage.color import rgb2gray
from skimage.transform import rotate
from deskew import determine_skew
image = io.imread('/content/img.jpg')
grayscale = rgb2gray(image)
angle = determine_skew(grayscale)
rotated = rotate(image, angle, resize=True) * 255
# io.imsave('output.png', rotated.astype(np.uint8))
cv2_imshow(rotated.astype(np.uint8))
here is the script i ran on my google colab to deskew it
import cv2
import numpy as np
from google.colab.patches import cv2_imshow
from skimage import io
def deskew(im, max_skew=10):
height, width , _= im.shape
# Create a grayscale image and denoise it
im_gs = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im_gs = cv2.fastNlMeansDenoising(im_gs, h=3)
# Create an inverted B&W copy using Otsu (automatic) thresholding
im_bw = cv2.threshold(im_gs, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
# Detect lines in this image. Parameters here mostly arrived at by trial and error.
lines = cv2.HoughLinesP(
im_bw, 1, np.pi / 180, 200, minLineLength=width / 12, maxLineGap=width / 150
)
# Collect the angles of these lines (in radians)
angles = []
for line in lines:
x1, y1, x2, y2 = line[0]
angles.append(np.arctan2(y2 - y1, x2 - x1))
# If the majority of our lines are vertical, this is probably a landscape image
landscape = np.sum([abs(angle) > np.pi / 4 for angle in angles]) > len(angles) / 2
# Filter the angles to remove outliers based on max_skew
if landscape:
angles = [
angle
for angle in angles
if np.deg2rad(90 - max_skew) < abs(angle) < np.deg2rad(90 + max_skew)
]
else:
angles = [angle for angle in angles if abs(angle) < np.deg2rad(max_skew)]
if len(angles) < 5:
# Insufficient data to deskew
return im
# Average the angles to a degree offset
angle_deg = np.rad2deg(np.median(angles))
# If this is landscape image, rotate the entire canvas appropriately
if landscape:
if angle_deg < 0:
im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
angle_deg += 90
elif angle_deg > 0:
im = cv2.rotate(im, cv2.ROTATE_90_COUNTERCLOCKWISE)
angle_deg -= 90
# Rotate the image by the residual offset
M = cv2.getRotationMatrix2D((width / 2, height / 2), angle_deg, 1)
im = cv2.warpAffine(im, M, (width, height), borderMode=cv2.BORDER_REPLICATE)
return im
pt = "/content/126016027_AO_BIZ-0000320520-Process_IP_Cheque.jpg"
image = io.imread(pt)
img = deskew(image)
cv2_imshow(img)
I am new to OpenCV and I am not even sure how to tackle this problem. I have this image of 500x500 pixel with red dots and white lines in it.
Considering each red dot as center and could I draw a fixed bounding box of 25X25 size around the red dot? I need to identify every red dot in the image.
Note: condition is that I need to find a bounding box of fixed size (25x25) and the red dot must be in the center of the bounding box.
Any help would be appreciated. Thank you in advance.
Another solution, using numpy slicing to get the red channel, where to create a mask of the red dots and cv2.findContours to get the bounding rectangles of the dots. We can use this info to draw the new 25 x 25 rectangles:
# Imports
import cv2
import numpy as np
# Read image
imagePath = "C://opencvImages//"
inputImage = cv2.imread(imagePath + "oHk9s.png")
# Deep copy for results:
inputImageCopy = inputImage.copy()
# Slice the Red channel from the image:
r = inputImage[:, :, 2]
# Convert type to unsigned integer (8 bit):
r = np.where(r == 237, 255, 0).astype("uint8")
# Extract blobs (the red dots are all the white pixels in this mask):
contours, _ = cv2.findContours(r, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Store bounding rectangles here:
boundingRectangles = []
# Loop through the blobs and draw a 25 x 25 green rectangle around them:
for c in contours:
# Get dot bounding box:
x, y, w, h = cv2.boundingRect(c)
# Set new bounding box dimensions:
boxWidth = 25
boxHeight = 25
# Center rectangle around blob:
boxX = int(x + 0.5 * (w - boxWidth))
boxY = int(y + 0.5 * (h - boxHeight))
# Store data:
boundingRectangles.append((boxX, boxY, boxWidth, boxHeight))
# Draw and show new bounding rectangles
color = (0, 255, 0)
cv2.rectangle(inputImageCopy, (boxX, boxY), (boxX + boxWidth, boxY + boxHeight), color, 2)
cv2.imshow("Boxes", inputImageCopy)
cv2.waitKey(0)
Additionally, I've stored the top left coordinate, width and height of the rectangles in the boundingRectangles list. This is the output:
Here is how you can use an HSV mask to mask out everything in your image except for the red pixels:
import cv2
import numpy as np
def draw_box(img, cnt):
x, y, w, h = cv2.boundingRect(cnt)
half_w = w // 2
half_h = h // 2
x1 = x + half_h - 12
x2 = x + half_h + 13
y1 = y + half_w - 12
y2 = y + half_w + 13
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0))
img = cv2.imread("red_dots.png")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
ranges = np.array([[100, 0, 0], [179, 255, 255]])
mask = cv2.inRange(img_hsv, *ranges)
img_masked = cv2.bitwise_and(img, img, mask=mask)
img_gray = cv2.cvtColor(img_masked, cv2.COLOR_BGR2GRAY)
contours, _ = cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
draw_box(img, cnt)
cv2.imshow("Image", img)
cv2.waitKey(0)
Output:
Notice at this part of the draw_box() function:
x1 = x + half_h - 12
x2 = x + half_h + 13
y1 = y + half_w - 12
y2 = y + half_w + 13
Ideally, instead of - 12 and + 13, it should be - 12.5 and + 12.5, but there cannot be half pixels in OpenCV, or an error would be thrown.
I want to make grid of dots, but I'm not sure this is the right way to do it.
from PIL import Image, ImageDraw
img = Image.new("RGB", (1000,1000), (0, 0, 0))
draw = ImageDraw.Draw(i)
w, h = img.size
step = 100
for n in range(step,w,step):
for x in range(step,h-step,step):
draw.point((n,x), fill="yellow")
img
Thanks in advance!
You can't pass a size parameter to point, so try ellipse:
from PIL import Image, ImageDraw
img = Image.new("RGB", (1000,1000), (0, 0, 0))
draw = ImageDraw.Draw(img)
w, h = img.size
step = 100
size = 10
for size in [1,25]:
for n in range(step,w,step):
for x in range(step,h-step,step):
draw.ellipse([n-size/2,x-size/2,n+size//2,x+size//2], fill="yellow")
img.save('size_{:d}.png'.format(size))
Which gives the following outputs:
I am trying to do image classification task and want to make sure my input data all have the same orientation.
The code bellow did not match all the images to the same directions and some flipped wrongly.
I will be thankful if anyone can help me with this matter, Thank you
original image 1
original image 2
import cv2
import numpy as np
import matplotlib.pyplot as plt
def getSubImage(rect, image):
center, size, theta = rect
center, size = tuple(map(int, center)), tuple(map(int, size))
M = cv2.getRotationMatrix2D( center, theta, 1)
dst = cv2.warpAffine(image, M, src.shape[:2])
out = cv2.getRectSubPix(dst, size, center)
return out
image = cv2.imread('orginal1.png')
im_bw = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blur = cv2.GaussianBlur(im_bw, (5,5), 0)
im_bw = cv2.Canny(blur, 10, 90)
contours, hierarchy = cv2.findContours(im_bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
out = getSubImage(rect, image)
cv2.imwrite('rotedorginal1.jpg', out)
plt.imshow(out)
plt.show()
You just need to build the matrix that rotates the image the right angle using cv2.getRotationMatrix2D and applying the operation with the matrix using cv2.warpAffine:
(x, y), (w, h), angle = cv2.minAreaRect(contours[0])
result = cv2.warpAffine(image, cv2.getRotationMatrix2D((image.shape[1]//2, image.shape[0]//2), angle-90, 1), (image.shape))
The code above transforms this image:
into this one:
I want to pre-process the patent plate and then enter an OCR.
In the part that I am, I have to do things in general, because I am working only with one image, but later they will be more and at different angles.
I am in the part where I insert filters, I wonder if the next part is to find the contours or straighten it (for this I am using hough transform).
Working on colab:
!pip install pytesseract
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pytesseract
plt.style.use('dark_background')
crop_img = cv2.imread('/content/0.png')
#IMG2GRAY
gray = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray)
#tresh
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
plt.imshow(thresh)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(thresh,(5,5),0)
th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
plt.imshow(th3)
plt.show()
The output I have, which I think this is bad:
And this is the image:
And this is the output when I rotate the image with HoughTransform:
The final result should be something like this (but remember that I will use the same preprocessing for other images):
I wrote a script in python to find the angle in which the license plate is rotated with and then rotating in the reverse order to deskew the license plate.
import numpy as np
import math
import cv2
def rotate_image(image, angle):
image_center = tuple(np.array(image.shape[1::-1]) / 2)
rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
return result
def compute_skew(src_img):
if len(src_img.shape) == 3:
h, w, _ = src_img.shape
elif len(src_img.shape) == 2:
h, w = src_img.shape
else:
print('upsupported image type')
img = cv2.medianBlur(src_img, 3)
edges = cv2.Canny(img, threshold1 = 30, threshold2 = 100, apertureSize = 3, L2gradient = True)
lines = cv2.HoughLinesP(edges, 1, math.pi/180, 30, minLineLength=w / 4.0, maxLineGap=h/4.0)
angle = 0.0
nlines = lines.size
#print(nlines)
cnt = 0
for x1, y1, x2, y2 in lines[0]:
ang = np.arctan2(y2 - y1, x2 - x1)
#print(ang)
if math.fabs(ang) <= 30: # excluding extreme rotations
angle += ang
cnt += 1
if cnt == 0:
return 0.0
return (angle / cnt)*180/math.pi
def deskew(src_img):
return rotate_image(src_img, compute_skew(src_img))
if __name__ == '__main__':
import cv2
img = cv2.imread('test.png')
corrected_img = deskew(img)
Deskewed License Plate:
You can apply some post-processing to completely remove the padded region, but the angle correction is the most important part for any detector.
Gist link: https://gist.github.com/zabir-nabil/dfb78f584947ebdb9f29d39c9737b5c6