Show multiple images in same window with Python OpenCV? - opencv

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.

Related

Changing number of channels in image

I am trying to convert number of channels to 1. For example I have image and I need to resize as 98,98 and I have done with this code -->
from PIL import Image
from skimage.transform import resize
import cv2
image = Image.open('//imagepath')
new_image =image.resize((98, 98))
and I get shape as (98,98,3) but I need it in the shape like (98,98,1). I have tried with this code -->
new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)
but I am getting error. How can I solve this?

How can I convert bounding box pixels of an image to white, and the background to black?

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!

OpenCV - Circle Detection Too Sensitive Even with Blur

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()

Show Grid line of 2d Map in image

i had search through anywhere on google and forums
but i couldnt found what i wanted.
hope someone could help me here...
i had generated a 2d map from octomap using map_server map_saver from a pcd file it generated 2 file which is pgm and yaml file
however the generated pgm file does not have grid line on it.
my question is is it possible to show grid line on the image generated from map_saver? or is there any other way to generate an image with grid line from a 2D map?
You may try this, change the map dimension and if you have a different orientation rotate the map accordingly.
import pylab as plt
import numpy as np
# Load the image
img = np.array(plt.imread("g_map.pgm"))
# assume dimension of map 20mx20m
map_dim_x = 20
map_dim_y = 20
# relationship between pixel and map
dx, dy = int(img.shape[0]/map_dim_x),int(img.shape[1]/map_dim_y)
grid_color = 0
img[:,::dy,] = grid_color
img[::dx,] = grid_color
plt.imshow(img)
plt.show()

check pixel's transparency in OpenCV

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.

Resources