Hi, just posting this on behalf of my 10yo son. He's working on a Python/OpenCV/GUI application and having some issues. Hoping someone might be able to point him in the right direction. Information as per below (maybe he needs to take a different approach?)
At the moment in my project I am having a problem with no errors. The only problem is the code isn't doing exactly what I want it to be. I can not tell if the blur is too strong, the blur is making the circle detection more sensitive or something else. My code is below.
I am trying to make the circle detection less sensitive by using a blur, however I can not tell what it's doing because there is no error.
What I want it to do is:
blur the image
ensure the circle detection is not to sensitive (not too many circles)
show the image unblurred and on the unblurred image show the circles from the blurred image
For an example, I should be able to detect moon craters.
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk, Image
import numpy as np
import cv2
root = tk.Tk()
root.title("Circle detecter")
root.geometry("1100x600")
root.iconbitmap('C:/Users/brett/')
def open():
global my_image
filename = filedialog.askopenfilename(initialdir="images", title="Select A File", filetypes=(("jpg files", "*.jpg"),("all files", "*.*")))
my_label.config(text=filename)
my_image = Image.open(filename)
tkimg = ImageTk.PhotoImage(my_image)
my_image_label.config(image=tkimg)
my_image_label.image = tkimg # save a reference of the image
def find_circles():
# convert PIL image to OpenCV image
circles_image = np.array(my_image.convert('RGB'))
gray_img = cv2.cvtColor(circles_image, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20,
param1=20, param2=60, minRadius=20, maxRadius=200)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0]:
# draw the outer circle
cv2.circle(circles_image, (i[0],i[1]), i[2], (0,255,0), 2)
# draw the center of the circle
cv2.circle(circles_image, (i[0],i[1]), 2, (0,0,255), 3)
# convert OpenCV image back to PIL image
image = Image.fromarray(circles_image)
# update shown image
my_image_label.image.paste(image)
tk.Button(root, text="Load Image", command=open).pack()
tk.Button(root, text="Find circles", command=find_circles).pack()
# for the filename of selected image
my_label = tk.Label(root)
my_label.pack()
# for showing the selected image
my_image_label = tk.Label(root)
my_image_label.pack()
root.mainloop()
Related
I have a set of images similar to this one:
And for each image, I have a text file with bounding box regions expressed in normalized pixel values, YOLOv5 format (a text document with rows of type: class, x_center, y_center, width, height). Here's an example:
3 0.1661542727623449 0.6696164480452673 0.2951388888888889 0.300925925925926
3 0.41214353459362196 0.851908114711934 0.2719907407407405 0.2961837705761321
I'd like to obtain a new dataset of masked images, where the bounding box area from the original image gets converted into white pixels, and the rest gets converted into black pixels. This would be and example of the output image:
I'm sure there is a way to do this in PIL (Pillow) in Python, but I just can't seem to find a way.
Would somebody be able to help?
Kindest thanks!
so here's the answer:
import os
import numpy as np
from PIL import Image
label=open(os.path.join(labPath, filename), 'r')
lines=label.read().split('\n')
square=np.zeros((1152,1152))
for line in lines:
if line!='':
line=line.split() #line: class, x, y, w, h
left=int((float(line[1])-0.5*float(line[3]))*1152 )
bot=int((float(line[2])+0.5*float(line[4]))*1152)
top=int(bot-float(line[4])*1152)
right=int(left+float(line[3])*1152)
square[top:bot, left:right]=255
square_img = Image.fromarray(square)
square_img=square_img.convert("L")
Let me know if you have any questions!
I want to read the window screen and display it by using the cv2.imshow() method.
Right now I am taking ScreenShot of the window and displaying that on the OpenCV window but it is also showing itself which I don't want.
which other approach should I adopt to get my result?
This is the code I am using right now.
while True:
img = screenshot()
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow("Test", img)
libraries, I am using are:
pyautogui # for Screenshot()
cv2 # for imshow()
numpy # for array()
This is what I don't want to happen.
Saved screenshot
https://i.stack.imgur.com/7PaC1.jpg
Code is taking Screenshot of imshow window as well but also I do not want to close or minimize the imshow window.
Q. Is there any other method to achive what I want?
My personal preference would be to use cv2.imwrite instead of cv2.imshow. but if you requirement needs you to use imshow, you can check out these 2 methods and see which fits your requirements
Option 1: Destroy the window before you take the screenshot and then make it again, the code for that would look like:
while True:
img = screenshot()
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow("Test", img)
cv2.destroyAllWindows()
I personally do not see a lot of merit to this method as it will majorly just keep creating and destroying windows
Option 2: OpenCV also allows you to move the window, you can use that to move the window before you are about to take the screenshot and then move it back in afterwards. The code for the same would look like:
while True:
# Just to check if img exists or not, needed for the 1st run of the loop
if 'img' in locals():
cv2.waitKey(100) #Without the delay, the imshow window will only keep flickering
cv2.moveWindow("Test", height, width)
img = screenshot()
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
height, width, ch = img.shape
cv2.imshow("Test", img)
cv2.moveWindow("Test", 0, 0)
The above 2 options were using the libraries that you already are using in your code. There is a third option too where you can minimize the window and then reopen it each time that you take a screenshot. You can find references to it over here, and here. And the code for the same should look like.
import ctypes
import win32gui
while True:
# Just to check if img exists or not,
# needed for the 1st run of the loop
if 'img' in locals():
cv2.waitKey(500) # Delay to stop the program from constantly opening and closing the window after itself
ctypes.windll.user32.ShowWindow(hwnd, 7)
# Window needs some time to be minimised
cv2.waitKey(500)
img = pyautogui.screenshot()
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow("Test", img)
hwnd = win32gui.GetForegroundWindow()
ctypes.windll.user32.ShowWindow(hwnd, 9)
I'm doing an Image Processing Project. I'd like to circle around the yellow spot as follow.
How to know that position? I tried to find the value from image data (list), but I still don't know how to know that position and how to circle it.
Please help me.
Here is my sample code:
import cv2
import numpy as np
cap = cv2.imread("img.jpg")
cap = cv2.resize(cap, (500, 500))
hsv_frame = cv2.cvtColor(cap, cv2.COLOR_BGR2HSV)
# Yellow color
low_yellow = np.array([21, 39, 64])
high_yellow = np.array([40, 255, 255])
yellow_mask = cv2.inRange(hsv_frame, low_yellow, high_yellow)
yellow = cv2.bitwise_and(cap, cap, mask=yellow_mask)
cv2.imshow("Frame", cap)
test = cv2.imshow("Yellow", yellow)
cv2.imwrite("yellowSpot.jpg", yellow)
key = cv2.waitKey(0)
Here is my solution using GRIP and its auto-generated code (it's a great GUI for building image processing functions in a graphical, easy-to-experiment way):
My image processing "pipeline":
Image processing functions:
Blur (to remove all the little noise spots from the image, and preserve the yellow spot)
HSV threshold (to only show the YELLOW spot)
Find Blobs (to find the yellow spots and put a CIRCLE around it)
Here is the link to download the GRIP software
Here is a link to all my files (including the auto-generated Python image processing pipeline)
I want to display original image left side and grayscale image on right side. Below is my code, I create grayscale image and create window, but I couldn't put grayscale image to right side. How can I do this?
import cv
import time
from PIL import Image
import sys
filePath = raw_input("file path: ")
filename = filePath
img = cv.LoadImage(filename)
imgGrayScale = cv.LoadImage(filename, cv.CV_LOAD_IMAGE_GRAYSCALE) # create grayscale image
imgW = img.width
imgH = img.height
cv.NamedWindow("title", cv.CV_WINDOW_AUTOSIZE)
cv.ShowImage("title", img )
cv.ResizeWindow("title", imgW * 2, imgH)
cv.WaitKey()
First concatenate the images either horizontally (across columns) or vertically (across rows) and then display it as a single image.
import numpy as np
import cv2
from skimage.data import astronaut
import scipy.misc as misc
img=cv2.cvtColor(astronaut(),cv2.COLOR_BGR2RGB)
numpy_horizontal_concat = np.concatenate((img, img), axis=1)
cv2.imshow('Numpy Horizontal Concat', numpy_horizontal_concat)
As far as I know, one window, one image. So create a new image with imgW*2 and copy the contents of the grayscale image at the region starting from (originalimage.width,0). The ROI capabilities may be helpful to you.
How to check is pixel transparent in OpenCV? I have a png image with transparent portions and I want to convert rgb image to hsv and then change hue of pixels. I need that transparent pixels remain transparent after the conversion.
Any help please.
You may try GDAL. It is compatible with CV2
These links may be useful.
Reading Raster Data with GDAL
GDAL API Tutorial
import gdal
from gdalconst import *
import numpy as np
ds = gdal.Open('lena.jpg', GA_ReadOnly)
B = ds.GetRasterBand(1)
G = ds.GetRasterBand(2)
R = ds.GetRasterBand(3)
A = ds.GetRasterBand(4) // Alpha
height, width = B.shape
img = np.zeros(height, width, 3)
img[:, :, 0] = B
img[:, :, 1] = G
img[:, :, 2] = R
// Do something you want
ds.GetRasterBand(1).WriteArray(new_B)
ds.GetRasterBand(2).WriteArray(new_G)
ds.GetRasterBand(3).WriteArray(new_R)
// The forth band dose not need to be changed
// Close image, the changes is writen in the source file
ds = None
// Note that I did not test this code
OpenCV does not support transperancy in images. (before v2.4, I'm not sure about the latest version)
You can try the solution at http://blog.developer.stylight.de/2010/05/how-to-load-alpha-channel-pngs-with.html and rebuild OpenCV, or you can use something like ImageMagick to extract the alpha layer (forum link) as a separate image and load it.