I recently starting coding a few days ago and I'm trying to write a program that crops images and then stacks them. I am currently still on step one. I want to make it where after the image is cropped, if is no already, rotate it to the horizontal position. Thank you for your time.
Edit: So I was able to get it to rotate, but now my rotated file has giant black boxes at the top and bottom, anyone know how to remove that.
from PIL import Image
# Convert list in variables
print("Type in the coordinates for the upper left (x1,y1) and bottom right (x2,y2) points")
coordinates = list(map(int, input("Separate values with a space (x1 y1 x2 y2): ").strip().split()))[:4]
x1, y1, x2, y2 = coordinates
print("Generating image...")
# Accessing file from folder
im = Image.open("C:\\Users\\Alex\\Desktop\\Ps\\2.tiff")
# Cropping function
selected_region = (x1, y1, x2, y2)
cropped_region = im.crop(selected_region)
# Current line I am trying to add to rotate images
selected_region = (x1, y1, x2, y2)
cropped_region = im.crop(selected_region)
if (y2-y1)>(x2-x1):
rotated_image = cropped_region.rotate(90)
else:
rotated_image = cropped_region
cropped_region.show()
cropped_region.save("C:\\Users\\Alex\Desktop\\Ps\\Output\\2_cropped.tiff", quality=95)
rotated_image.save("C:\\Users\\Alex\Desktop\\Ps\\Output\\rotated.tiff", quality=95)
Also, hopefully this isn't asking for too much. So in this code, I am cropping one image, is there a way I can repeat this for all (about 500) images in the same folder (all labelled test1.tiff, test2.tiff, test3.tiff...)
Related
My solution is as follows:
import cv2
import numpy as np
def sum_all_pixels(image, x1, y1, x2, y2, c1=0, c2=3):
'''
INPUTS: the image, the coordinates of the rectangle, and the channels
OUTPUT: sum of all pixels of the image within the rectangle
image: the path to the image
x1, y1: the coordinates of the top-left point of the rectangle
x2, y2: the coordinates of the bottom-right point of the rectangle
c1, c2: the range of the RGB color channels. By default, it assumed the sum is to be calculated across all 3 color channels
'''
img = cv2.imread(image)
return np.sum(img[y1:y2, x1:x2, c1:c2])
Is there any better, more efficient, algorithm to do this?
If you can preprocess your images, you could store the integral images(summed-area table) first:
img = cv2.imread(image)
int_img = cv2.integral(img)
int_img = int_img[1:,1:]
cv2.imwrite(filename, int_img)
Then for calculating the sum:
int_img = cv2.imread(filename)
sum = int_img[y2, x2] - int_img[y1, x2] - int_img[y2, x1] + int_img[y1, x2]
Since images in openCV are numpy arrays, you're pretty much doing this as fast as is possible.
If you're using a normal list, using the sum function in Python would be faster.
I have an image where I am creating rectangle over a specified area. The image is :
I am reading this image passing it through yolo algorithm gives me co-ordinates for rectangle around this gesture
the x1 , y1 , x2 , y2 values are
print(x1 , y1 , x2 , y2)
tensor(52.6865) tensor(38.8428) tensor(143.1934) tensor(162.9857)
Using these to add a rectangle over the image
box_w = x2 - x1
box_h = y2 - y1
color = bbox_colors[int(np.where(unique_labels == int(cls_pred))[0])]
# Create a Rectangle patch
bbox = patches.Rectangle((x1, y1), box_w, box_h, linewidth=2, edgecolor=color, facecolor="none")
# Add the bbox to the plot
ax.add_patch(bbox)
It results in the follwing image :
Now, I want to blacken everything around this square. For this purpose i am saving the above image and reading it back then using opencv to blacken the rest using following code.
x1 = int(x1)
y1 = int(y1)
x2 = int(x2)
y2 = int(y2)
# read image
img = cv2.imread(output_path)
#creating black mask
mask = np.zeros_like(img)
mask = cv2.rectangle(mask, (x1, y1), (x2,y2), (255,255,255), -1)
# apply mask to image
result = cv2.bitwise_and(img, mask)
# save results
cv2.imwrite(output_path, result)
I am getting the following image as result :
There are 2 issues :
cv2.rectangle only takes integer values as co-ordinates
May be x, y axis has different direction in yolo and open cv. Just guessing cause integers co-ordinate values should not be giving such vast difference from the rectangle.
This is being done in Jupyter notebook on Win 10.
The purpose of this program is to map out the corners and edges of a room, here is where I'm at right now:
The image on the top right is my result, and the image on the top left is my input. Currently, I am using canny edge detection with a gaussian filter. But as you can see, there are a lot of random lines coming from other details in the image.
My goal is this:
So far, I've tried,
Only showing lines that are flat (0 or infinite slope):
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
if math.isclose(x1, x2, tol_abs=25) or math.isclose(y1, y2, tol_abs=10):
cv2.line(bgrimg, (x1, y1), (x2, y2), (0, 255, 0), 1)
But this resulted in me losing some of the important lines.
Next, I tried to only show lines on the edges of the image:
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
if y1 > 100 and y2 > 100:
cv2.line(bgrimg, (x1, y1), (x2, y2), (0, 255, 0), 1)
This somewhat works for the top, but since the sides could be anywhere in the picture, I can't determine exactly where they will be.
Is there a way to solve this? If not, would it be possible with machine learning?
Starting from the information obtained by Canny. Could:
1 - Determine a good reference for the horizontal line,
2 - Determine a good reference for the right diagonal line
3 - Determine a good reference for the left diagonal line
4 - From the extension of these reference lines you can find the intersections.
Some intersections will be good, others bad.
It is a good intersection if the angle formed by the horizontal reference line and the oblique reference line are the same or similar both to the right and to the left.
As in the image I added here:
https://i.stack.imgur.com/OYS2c.png
I have a image (black and white) with a high resolution and I need the information if my drawing command (e.g cv2.line(...)) has changed the image. Comment: There is the probability, that the pixel are already in the color of cv.line(), then the image has not changed.
Currently I am comparing the whole image, whcih is very slow (I have to do this check several 1000 times.)
img = LARGE IMAGE
#make copy
imgBuffer= img.copy()
#draw on copy
imgBuffer= cv2.line(imgBuffer, point1, point2, colorBlack, 1);
# calc if there is any difference in the images
diffExist = np.any(cv2.absdiff(drawnImageBuffer, contourImage))
Does somebody have an better more efficient idea to do it?
An obvious speed improvement you can make is by only comparing the parts of the image that can possibly have changed by drawing a line connecting your two given points-- the sub-image bounded by the two points that you pass in to cv2.line().
So it would be faster to run:
img_buffer = orig_img.copy()
x1, y1 = point1
x2, y2 = point2
# make sure x1 and y1 are the lower values
if x2 < x1:
x1, x2 = x2, x1
if y2 < y1:
y1, y2 = y2, y1
cv2.line(img_buffer, point1, point2, colorBlack, 1)
diff_exist = np.any(cv2.absdiff(img_buffer[y1:y2, x1:x2],
orig_img[y1:y2, x1:x2]))
how can i resize my rectangle(canvas_bar) ?
am making hp bar to follow the object(monster)
and need to resize by it hp
hp = 100
hp_x = 100/5
canvas.create_rectangle(self.x, self.y, self.x+20, self.y+hp_x,
fill='red')
self.canvas.move(self.canvas_bar, self.vx, self.vy)
enter image description here
You can use the coords method to change the coordinates of an object.
The following example gets the current coordinates for the item identified by self.canvas_bar, and then makes the bar 100px wider:
(x0, y0, x1, y1) = self.canvas.coords(self.canvas_bar)
self.canvas.coords(self.canvas_bar, (x0, y0, x1+100, y1))