On Google Colab I can have a picture shown inline using the following
!curl -o logo.png https://colab.research.google.com/img/colab_favicon_256px.png
import cv2
img = cv2.imread('logo.png', cv2.IMREAD_UNCHANGED)
cv2_imshow(img)
I would like to draw a rectangular on the picture (inline)
tt=cv2.rectangle(img, (210, 826), (270, 900), (250, 255, 0), 20 )
cv2_imshow(tt)
but this does not work
Some problems here:
The .png is 256x256, so your coordinates are unreasonable (mostly off-screen).
The .png has transparency so the lack of a fourth coordinate in your color spec means using an alpha of zero, so the rectangle is not visible.
cv2.rectangle modifies its first argument, so better to keep referring to img and avoid the confusion of expecting it to remain unchanged by referring to tt later.
Here's example code that results in a visible rectangle:
!curl -s -o logo.png https://colab.research.google.com/img/colab_favicon_256px.png
import cv2
from google.colab.patches import cv2_imshow
img = cv2.imread('logo.png', cv2.IMREAD_UNCHANGED)
print(img.shape)
cv2.rectangle(img, (128, 128), (163, 172), (0, 255, 0, 255), 2)
cv2_imshow(img)
Related
I have a binary mask, how to apply a Gaussian kernel of standard unit deviation on the border of the mask to smooth border?
When applying Gaussian blur filter on a mask, it blurs only the borders of the mask.
Example:
import cv2
orig_img = cv2.imread('mask.png', cv2.IMREAD_GRAYSCALE) # Read image as Grayscale.
blur = cv2.GaussianBlur(orig_img, (15, 15), 0)
Result:
In case you want to keep the mask unmodified, and smooth only the pixels around the mask, I suggest using few iterations, and taking the maximum.
Getting the maximum between the original image and blurred image, makes sure that the original mask pixels remains unchanged, because their values is 255 (maximum possible value).
Here is a code sample:
import cv2
orig_img = cv2.imread('mask.png', cv2.IMREAD_GRAYSCALE) # Read image as Grayscale.
img = orig_img.copy()
for i in range(10):
blur = cv2.GaussianBlur(img, (15, 15), 0)
img = cv2.max(blur, img) # Getting the maximum in order to mask the margins brighter
blur = cv2.max(orig_img, img) # Getting the maximum for keeping the original mask pixels unmodified.
cv2.imshow('blur', blur)
cv2.waitKey()
cv2.destroyAllWindows()
Result:
Another option is using morphological dilation before GaussianBlur:
import cv2
orig_img = cv2.imread('mask.png', cv2.IMREAD_GRAYSCALE) # Read image as Grayscale.
img = cv2.dilate(orig_img, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7)))
blur = cv2.GaussianBlur(img, (15, 15), 0)
blur = cv2.max(blur, orig_img) # Getting the maximum for keeping the original mask pixels unmodified.
cv2.imshow('blur', blur)
cv2.waitKey()
cv2.destroyAllWindows()
Result:
Is there any way to remove icon from image that in original didn't had the icon.
Maybe with help of hexdump or something?
Here is an example of image.
is there a way to remove the heart icon from it?
*I don't really need this image it is just for example
One method is to use color thresholding to obtain a binary mask which can be used to isolate the desired regions to keep. Once we have this mask, we bitwise-and to effectively remove the heart
After color thresholding with a HSV lower and upper range, we obtain this mask
To remove the heart, we invert the mask which represents all regions in the image that we want to keep then bitwise-and with the input image. Since you didn't specify what you want to replace it with, I've just colored the removed region with white. Here's an implementation using Python and OpenCV
import numpy as np
import cv2
image = cv2.imread('1.jpg')
original = image.copy()
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 138, 155])
upper = np.array([179, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
invert = 255 - mask
result = cv2.bitwise_and(original, original, mask=invert)
result[invert==0] = (255,255,255)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey()
I'm attempting to render barcodes in Go with user-input colours for both the data and background, and although the barcodes themselves are produced as expected in black and white, attempting to use them as a mask image in "image/draw"'s draw.DrawMask function results in full pass-through of the source image, ignoring the mask entirely.
This is very much counter to the examples given in the Go blog post on the image/draw package.
I've reduced the problem down to a fairly minimal example, a simple white square on a black background as a mask with uniform colours as source and destination, and the behaviour continues. I'm clearly failing to understand some element of how this function behaves, but attempts at finding similar problems others have encountered all seem to end with a different approach to the problem entirely (eg another library to do the job), rather than understanding the mistake in the usage of draw.DrawMask.
The code I've posted includes a function for writing the three output images to BMP files, but this behaviour is repeated if any other method of saving the image.Image data to a file is used.
package main
import (
"bytes"
bmp "golang.org/x/image/bmp"
"image"
"image/color"
"image/draw"
"io/ioutil"
"os"
)
func main() {
//Use one rectange to make all new images
bounds := image.Rect(0, 0, 100, 100)
//Generate a 20px wide white square in the centre of a black background
mask := image.NewNRGBA(bounds)
draw.Draw(mask, bounds, image.NewUniform(color.Black), image.ZP, draw.Src)
draw.Draw(mask, image.Rect(40, 40, 60, 60), image.NewUniform(color.White), image.ZP, draw.Src)
//Generate a blue image of the right size - this is unnecessary, but shouldn't hurt
blue := image.NewNRGBA(bounds)
draw.Draw(blue, bounds, image.NewUniform(color.NRGBA{B: 255, A: 255}), image.ZP, draw.Src)
//Copy the blue image into what is the desired output - also unnecessary, but will help to demonstrate each step is working independently
result := image.NewNRGBA(bounds)
draw.Draw(result, bounds, blue, image.ZP, draw.Src)
//Use mask to draw green onto the blue - but only inside the 20px square (in theory)
draw.DrawMask(result, bounds, image.NewUniform(color.NRGBA{G: 255, A: 255}), image.ZP, mask, image.ZP, draw.Over)
writeImageToBMP(blue, "blue.bmp")
writeImageToBMP(mask, "mask.bmp")
writeImageToBMP(result, "result.bmp")
}
func writeImageToBMP(img image.Image, filename string) {
//This part isn't relevant to the problem, I just don't know a better way to show content of an image
var imgBytes bytes.Buffer
bmp.Encode(&imgBytes, img)
ioutil.WriteFile(filename, imgBytes.Bytes(), os.ModeExclusive)
}
I would expect the code above to produce three images:
A blue square, 100px by 100px
A black square, 100px by 100px, with a 20px by 20px white square in its centre
A blue square, 100px by 100px with a 20px by 20px green square in its centre
The first two appear as expected, but the third is entirely green.
TLDR: The mask isn't supposed to be black and white, that's just how they rendered it for visual effect. The mask is supposed to be opaque where the Src should be used, and transparent where the Src should not be used.
Replace the mask generation in my original code with the following and it all suddenly works as expected. (Replace Black with Transparent, replace White with Opaque):
mask := image.NewNRGBA(bounds)
draw.Draw(mask, bounds, image.NewUniform(color.Transparent), image.ZP, draw.Src)
draw.Draw(mask, image.Rect(40, 40, 60, 60), image.NewUniform(color.Opaque), image.ZP, draw.Src)
I spent a full day and a half banging my head against a wall, finally gave in and posted to SO for the first time, then immediately solved my own problem as soon as I stopped thinking about it, like an idiot.
How to detect eye movement, when it's closed. I am able to detect the closed eye region in a thermal video with finding the hottest spot then drawn a circle around that point.with the trial and error i was roughly able to estimate the eye corner co-ordinates then i cropped out the eye region[2] from the video. The next task is to detect its movement.
import numpy as np
import cv2
import scipy
from matplotlib import pyplot as plt
from PIL import Image
from collections import Counter
blur_radius = 1.0
threshold = 50
video = cv2.VideoCapture('12.avi')
while True:
ret, frame = video.read()
frame = frame[:,1:600]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (15,15), 0)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(gray)
image = frame
(x,y) = maxLoc
cv2.circle(image, maxLoc, 15, (255, 0, 0), 2)
cv2.rectangle(image,(maxLoc),(390,190),(0,255,0),2)
roi = frame [y:190,x:390]
try:
roi = cv2.resize(roi, None, fx=4, fy=4, interpolation=cv2.INTER_AREA)
cv2.imshow("Eye",roi)
cv2.imshow("Eyecorner", image)
except:
print''
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video.release()
cv2.destroyAllWindows()
[1]
[2]
[1]: https://i.stack.imgur.com/jayfp.jpg = detected eye in a single frame
[2]: https://i.stack.imgur.com/MgEe7.jpg = the cropped eye region from a thermal video
Since you already have the hotspot containing the eye and the coordinates of the eye corners, can't you simply measure the distance between the center of the hotspot and the center point between the two corners at every frame and examine its rate of change? You didn't mention how precise the measurements are, but provided that they are 100% correct and that the head doesn't move too much (perspective doesn't change), then it should work. Otherwise you need another way to determine a frame of reference.
I am plotting a greyscale version of this image:
SOURCE: http://matplotlib.org/examples/pylab_examples/griddata_demo.html
I have used the following code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from PIL import Image
file_name = 'griddata_demo.png'
def func_grey(fname):
image = Image.open(fname).convert("L")
arr = np.asarray(image)
plt.imshow(arr, cmap = cm.Greys_r)
plt.show()
func_grey(file_name)
Display image as grayscale using matplotlib
The setup I am working is has python 2.7 and Pandas and I have installed Pillow with easy install.
Background information about the image and the requirements:
The image come from data found here. Ideally, the greyscale
version of this image should be generated directly from this raw
data.i.e. do not save it as a colored image and then try to convert
to greyscale - rather just produce a greyscale version of the plot.
I do not know the colors that correspond to the z-values - these
colors can be set arbitrarily.
The color map of the image can also be chosen arbitrarily - there is no preference. It
is the greyscale version that is of concern.
My question is related to the color scheme shown in the colorbar. I need to display a color scheme where the color bar has colors from light grey (lowest intensity) to dark grey (highest intensity).
After running the above code, a greyscale image is produced. In the color bar of the greyscale image, the intensity level -0.36 is dark grey. At 0.00, it is light grey. But then 0.48 is also dark grey.
Question:
Is is possible to change the colormap such that -0.36 is light grey and 0.48 is dark grey? I mean, is it possible to display to colorbar from light to dark?
I think this question may be about how to use a grayscale colormap in matplotlib. If so, then it's straightforward. Here's an example using different colormaps (based on the code for the op image):
from numpy.random import uniform, seed
from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
import numpy as np
# make up data.
#npts = int(raw_input('enter # of random points to plot:'))
def f(spi, the_colormap):
plt.subplot(spi)
seed(0)
npts = 200
x = uniform(-2, 2, npts)
y = uniform(-2, 2, npts)
z = x*np.exp(-x**2 - y**2)
xi = np.linspace(-2.1, 2.1, 100)
yi = np.linspace(-2.1, 2.1, 200)
zi = griddata(x, y, z, xi, yi, interp='linear')
CS = plt.contour(xi, yi, zi, 15, linewidths=0.5, colors='k')
CS = plt.contourf(xi, yi, zi, 15, cmap=the_colormap,
vmax=abs(zi).max(), vmin=-abs(zi).max())
plt.colorbar() # draw colorbar
# plot data points.
plt.scatter(x, y, marker='o', c='b', s=5, zorder=10)
plt.xlim(-2, 2)
plt.ylim(-2, 2)
plt.title('griddata test (%d points)' % npts)
f(131, plt.cm.rainbow)
f(132, plt.cm.gray)
f(133, plt.cm.hot)
plt.show()
If one actually wants to convert to grayscale using PIL (a far less favorable, but sometimes necessary task), it's best to start with a colormap that has monotonic brightness, like hot above, but not rainbow. Also, in the comments I suggested using cubehelix but that's not standard with matplotlib, instead see here. See here for an image of the available matplotlib colormaps.
this solution works for me, and is a lot simpler
from PIL import Image
im = Image.open("image.png")
im.convert('L').show()
im.convert('L').save("image.png")
note that if you want to mix up the file types, you can (.png to .jpg for example)