Seperate two pictures with black beam in imshow - python

I want to show two images and seperate them visually with a black beam in Python.
My Problem is, that I get not the original colors with the cv2.imshow()function in the Plot-Window.
Here is my Code:
import cv2
import numpy as np
imgloc = 'path\Dosen_py.png'
img = cv2.imread(imgloc)
hight = np.shape(img)[0]
beam = np.zeros((hight,10,3))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_3_channel = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
horizontal = np.hstack((img,beam,gray_3_channel))
small = cv2.resize(horizontal, (0,0), fx=0.5, fy=0.5)
cv2.imwrite("combi.png",small)
cv2.imshow("Combi",small)
cv2.waitKey()
After running the code i get the following picture in the plot window:
The saved "combi.png"-file shows the right colors:
If I plot the two pictures without the black beam, i get the original colours,too.
Does anyone know whats wrong with this black beam?
System: Windows 10
IDE: Spyder (Python 2.7)

The default np.ndarray.dtype is np.float64, while for image, it should be np.uint8.
This line:
beam = np.zeros((hight,10,3))
and then, the beam、horixxx and small all are np.float64. So you display the float64. But when write, truncated to np.uint8.
It should be changed to:
beam = np.zeros((hight,10,3), np.uint8)

Related

Python Code containing OpenCV is not detecting object in my image

I am very new to OpenCV and Python. So, for my first project to recognize objects, I am using a small test file in python. This is the test file
import cv2
from matplotlib import pyplot as plt
# Opening image
img = cv2.imread("image.jpg")
# OpenCV opens images as BRG
# but we want it as RGB We'll
# also need a grayscale version
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Use minSize because for not
# bothering with extra-small
# dots that would look like STOP signs
stop_data = cv2.CascadeClassifier('cascade.xml')
found = stop_data.detectMultiScale(img_gray,
minSize=(20,20))
amount_found = len(found)
if amount_found != 0:
# There may be more than one
# sign in the image
for (x, y, width, height) in found:
# We draw a green rectangle around
# every recognized sign
cv2.rectangle(img_rgb, (x, y),
(x + height, y + width),
(0, 255, 0), 5)
# Creates the environment of
# the picture and shows it
plt.subplot(1, 1, 1)
plt.imshow(img_rgb)
plt.show()
The tutorial that I saw told me to use a premade cascade.xml file. However, I wanted to train my cascade file to recognize a simple apple logo, which I cropped from a photo. I copy pasted the same image multiple times into one folder titled p. For the negative images, I used a folder titled n. After this, I used the GUI cascade trainer and trained a cascade file. However, when I use the same image (uncropped) in the python program, there is no output.
This is the image which I used to train:
This is the original image which I put in the python script
The original image is of size 422612 and the cropped image is of size 285354. I had set the size in the trainer to height=20 and width=15.
These are my settings:
Folder p:
Output of program:
Cascade GUI log end
NEG count : acceptanceRatio 0 : 0
Required leaf false alarm rate achieved. Branch training terminated.
Could someone tell me where I am going wrong ? Please ask if I have to provide anymore information. Is there any ratio relation between the positive image and the actual image that I am missing on ?
UPDATE: I added some more negative images and am now getting this output:

Why cv2.write saves black images?

hi folks, greetings
am using this code that I found on the web, to apply a wiener filter on an image, the code :
from scipy.signal.signaltools import deconvolve
from skimage import color, data, restoration
img = color.rgb2gray(img)
from scipy.signal import convolve2d
psf = np.ones((5, 5)) / 25
img = convolve2d(img, psf, 'same')
img += 0.1 * img.std() * np.random.standard_normal(img.shape)
deconvolved_img = restoration.wiener(img, psf, 1100)
f, (plot1, plot2) = plt.subplots(1, 2)
plot1.imshow(img)
plot2.imshow(deconvolved_img)
plt.show()
cv2.imwrite("wiener result 2.jpeg",deconvolved_img)
the issue is when I plot the result using Matplotlib I get this :
but when I type cv2.imwrite("wiener result 2.jpeg",deconvolved_img) to save the image, I get this :
why do I get a black image when I save it ??
There are two ways to save your images as a file:
Method 1: Using matplotlib
Since you are using matplotlib library to show the image plt.show(), you can use the same library to save your plots as well using plt.savefig()
plot1.imshow(img)
plot2.imshow(deconvolved_img)
plt.savefig('path_to_save) # mention the path you want to save the plots
plt.show()
Method 2: Using OpenCV
You can also save your file using OpenCV.
But prior to saving your image there is a conversion required. The image variable deconvolved_img is of float data type, with values ranging between [0 - 1]. Hence when you save such images they are perceived as a black image.
In OpenCV you can convert your image to int data type and scaling the pixel intensities between the expected [0 - 255] using cv2.normalize() function:
result = cv2.normalize(deconvolved_img, dst=None, alpha=0, beta=255,norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
cv2.imwrite('path_to_save', result) # mention the path you want to save the result

Create image mask in Python for DNG and processing

I have a RAW image that is saved as .dng from a phone's camera. I want to segment the colors with the OpenCV library in Python. The picture is primarily black and green and I want to get the values of the green parts of the image. I've not worked with images in this way and am completely clueless. The tutorial I am following says to convert the image to H.S.V. color space and to use a mask, but I'm running into problems with the mask, if not in other steps. I'm using Google Colabs.
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os
from google.colab import drive
import imageio
import scipy.misc
import skimage.filters
import skimage.metrics
from PIL import Image
# Colabs...
!pip install rawpy
import rawpy
# Colabs...
!pip install ExifRead
import exifread
#image
plate = rawpy.imread('/content/drive/MyDrive/Colab Notebooks/Copy of 0724201706a.dng')
#EXIF
plate_x = open('/content/drive/MyDrive/Colab Notebooks/Copy of 0724201706a.dng', 'rb')
#There are several lines returned. I've left this out for now...
plate_tags = exifread.process_file(plate_x)
plate_tags
plt.imshow(plate.raw_image)
plate_rgb = plate.postprocess( use_camera_wb=True)
plt.imshow(plate_rgb)
plate_rgb.shape
(5312, 2988, 3)
These are a slightly edited RGB, the green channel, and blue channel of the RGB image.
Histograms of the values for each channel in R.G.B. image. The other channels are 0, but green has various values.
I supplied all this info to try to describe the RAW image and the R.G.B.
The tutorial says to convert to the H.S.V. color space. I saw somewhere that the image comes in as B.G.R., so I tried two approaches:
plateRGB_hsv = cv2.cvtColor(plate_rgb, cv2.COLOR_RGB2HSV)
plateBGR_hsv = cv2.cvtColor(plate_rgb, cv2.COLOR_BGR2HSV)
# A lower and upper threshold for mask
hsv_green_lo = (59, 100, 135) #h = 50, s = 100, v = 135)
hsv_green_hi = (75, 250, 255) #h = 75, s = 250, v = 255)
plateRGB_hsv.shape
(5312, 2988, 3)
# Create mask
green_thr = cv2.inRange(plateRGB_hsv, hsv_green_lo, hsv_green_hi)
# Apply mask
img_msk = cv2.bitwise_and(plateRGB_hsv, plateRGB_hsv, green_thr)
plt.subplot(1,2,1)
plt.imshow(green_thr)
plt.subplot(1,2,2)
plt.imshow(img_msk)
plt.show()
Output of the inRange (mask layer creation) and bitwise_and (mask application).
rgb_out = cv2.bitwise_and(plate_rgb, plate_rgb, green_thr)
plt.imshow(rgb_out)
plt.plot()
Apply mask and this is output.
So I didn't seem to create the mask properly? And with the bad mask, there was no change when bitwise_and ran it looks like? I don't know why the mask failed. Is the fact that the R.G.B. or H.S.V. is in three channels complicating the mask and mask application?
The image is here.
EDIT after comments and submitted answer:
I was not clear about what I want my output to look like. I said "green", but really I want it to look like this:
I made a new array with just the green channel as advised.
green_c = plate_rgb[...,1]
But now, I'm confused about how to create a mask. Since the array is just one level, I think of it as a "layer", like in G.I.S. or GIMP, how do I change the unwanted values to black? Sorry if this is obvious. I'm still pretty new to Python.
I am not really sure what you think the problem is. Basically, the Red and Blue channels of your image are empty (look at their mean values in the output below) and you may as well discard them and just use the Green channel as your mask.
#!/usr/bin/env python3
import rawpy
import matplotlib.pyplot as plt
import numpy as np
# Load and process raw DNG
plate = rawpy.imread('raw.dng')
rgb = plate.postprocess()
# Show what we've got
print(f'Dimensions: {rgb.shape}, dtype: {rgb.dtype}')
R = rgb[...,0]
print(f'R channel: min={R.min()}, mean={R.mean()}, max={R.max()}')
G = rgb[...,1]
print(f'G channel: min={G.min()}, mean={G.mean()}, max={G.max()}')
B = rgb[...,2]
print(f'B channel: min={B.min()}, mean={B.mean()}, max={B.max()}')
# Display green channel
plt.imshow(G, cmap='gray')
plt.show()
Output for your image
Dimensions: (5312, 2988, 3), dtype: uint8
R channel: min=0, mean=0.013673103558813567, max=255
G channel: min=0, mean=69.00267554908389, max=255
B channel: min=0, mean=0.017269189710649828, max=255
Keywords: Python, image processing, rawpy, DNG, Adobe DNG format.

How to erase the dotted watermark from set of similar images?

I want to automate the task of entering set of images into a number generating system & before that i like to remove a dotted watermark which is common across these images.
I tried using google, tesseract & abby reader, but I found that the image part that does not contain the watermark is recognized well, but the part that is watermarked is almost impossible to recognize.
I would like to remove the watermark using image processing. I already tried few sample codes of opencv, python, matlab etc but none matching my requirements...
Here is a sample code in Python that I tried which changes the brightness & darkness:
import cv2
import numpy as np
img = cv2.imread("d:\\Docs\\WFH_Work\\test.png")
alpha = 2.5
beta = -250
new = alpha * img + beta
new = np.clip(new, 0, 255).astype(np.uint8)
cv2.imshow("my window", new)
Unusually, i dont know the watermark of this image consists how many pixels. Is there a way to get rid of this watermark OR make digits dark and lower the darkness of watermark via code?
Here is watermarked image
I am using dilate to remove the figures, then find the edge to detect watermark. Remove it by main gray inside watermark
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('test.png', 0)
kernel = np.ones((10,10),np.uint8)
dilation = cv2.dilate(img,kernel,iterations = 1)
erosion = cv2.erode(dilation,kernel,iterations = 1)
plt.imshow(erosion, cmap='gray')
plt.show()
#contour
gray = cv2.bilateralFilter(erosion, 11, 17, 17)
edged = cv2.Canny(gray, 30, 200)
plt.imshow(edged, cmap='gray')
plt.show()

Python2: Resize image plotted using Matplotlib

I'm coding using Jupyter Notebook with Python 2 + OpenCV 3, and I need to show my results using images. The images are very small and it's hard to observe the results.
from matplotlib import pyplot as plt
import cv2
thresh = 127
maxValue = 255
file_path = "dados/page1.jpg"
%matplotlib notebook
image = cv2.imread(file_path)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
plt.title("First image")
plt.imshow(gray_image)
Output image
Image is too small. How can I zoom it?
As usual you can set the figure size using
plt.figure(figsize=(8,12))
The maximal figure size is (50,50), however you need to choose sensible values yourself depending on your screen size.

Categories

Resources