Image conversion Function using python and open - python

Recently I have started learning opencv and python for image processing .I am facing problems with writing a function .
I was given a task as follows:
Write a function in python to open a color image and convert the image into grayscale.
You are required to write a function color_grayscale(filename,g) which takes two arguments:
a. filename: a color image (Test color image is in folder “Task1_Practice/test_images”. Pick first image to perform the experiment.)
b. g: an integer
Output of program should be a grayscale image if g = 1 and a color image otherwise.
The code i wrote is as follows :
import cv2
def color_grayscale(filename,g):
filename = cv2.imread("a15.jpg")
" Enter Value of g:"
if g == 1:
gray = cv2.cvtColor(filename, cv2.COLOR_BGR2GRAY)
img = cv2.imshow("gray",gray)
else:
img = cv2.imshow("original",filename)
return(img)
color_grayscale("a15.jpg",1)
The code when run gives no output whatsoever.

cv2.imshow should be followed by waitKey function which displays the image for specified milliseconds. Otherwise, it won’t display the image. For example, waitKey(0) will display the window infinitely until any keypress (it is suitable for image display). waitKey(25) will display a frame for 25 ms, after which display will be automatically closed. (If you put it in a loop to read videos, it will display the video frame-by-frame)
Just add cv2.waitKey(0) before you return img and then it will display the grayscale image

Related

Input while cv2 shows an image

I would like to get input when I am showing an image using OpenCV's imshow() function. But If I do so, the image doesn't show correctly and a grey image appears instead.
It works if I use destroyAllWindows() command, but is there a proper solution for this?
def write_solution(crop):
cv2.imshow('Frage',crop)
ans = input("Antwort: ")
cv2.waitKey(0)
cv2.destroyAllWindows()
return ans

Displayed image from a time frame of a video has the wrong color [duplicate]

This question already has answers here:
OpenCV giving wrong color to colored images on loading
(7 answers)
Closed last year.
i tried to extract a time frame of a video, and show it as image(JPEG). But unfortunately the displayed image using PIL.Image.fromarray() is bluer than it supposed to be. the tricky part is, when i save it first (using cv2.imwrite) and open that new file using PIL.Image.open(), the image has the right color.
I thought it has something to do with the RGB array composition, but then i checked it, and both array (direct from the frame and from the Image.open()) are exactly the same.
Is there anything i can do to show the right image without saving it as an external file beforehand?
Thank you.
def TimeFrame(file, tf):
capture = cv2.VideoCapture(file)
frameCount = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
capture.set(cv2.CAP_PROP_POS_FRAMES, tf)
_, frame = capture.read()
directTF = Image.fromarray(frame)
cv2.imwrite("12345678999.jpg", frame)
image = Image.open("12345678999.jpg")
note: file is the name of the video and tf is the certain timeframe that you want to extract the image from.
OpenCV uses BGR as its default colour order for images
Use cv2.cvtColor(img, cv2.COLOR_BGR2RGB) before displaying
OpenCV uses BGR, PIL uses RGB.
You might want to try
directTF = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
to have OpenCV flip those channels before you ask PIL to read the array.

Is it possible to change a part of the background color of an image, when the image is a table?

I am using pytesseract, pillow,cv2 to OCR an image and get the text present in the image. Since my input is a scanned PDF document, I first converted it into an image (JPEG) format and then tried extracting the text. I am only half way there. The input is a table and the titles are not being displayed, since the titles have a black background. I also tried getstructuringelement but unable to figure out a way Here is what I did-
import cv2
import os
import numpy as np
import pytesseract
#import pillow
#Since scanned PDF can't be handled by pdf2image, convert the scanned PDF into a JPEG format using the below code-
filename = path
from pdf2image import convert_from_path
pages = convert_from_path(filename, 500) for page in pages:
page.save("dest", 'JPEG')
imgname = "path"
oriimg = cv2.imread(imgname,cv2.IMREAD_COLOR)
cv2.imshow("original image", oriimg)
cv2.waitKey(0)
#img = cv2.resize(oriimg,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_CUBIC)
img = cv2.resize(oriimg,(700,1500),interpolation=cv2.INTER_AREA)
#here length height
cv2.imshow("lol", img)
cv2.waitKey(0)
cv2.imwrite("changed_dimensionsimgpath", img)
import PIL.Image
image = cv2.imread(imgname,cv2.IMREAD_COLOR)
grayedimg = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) grayedimg =
cv2.threshold(grayedimg, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imwrite("H://newim.jpg", grayedimg)
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files (x86)\Tesseract-
OCR\tesseract.exe"
text = pytesseract.image_to_string(PIL.Image.open("path"))
print(text)
My input table looks like below. The regions which have black background are not being identified by OCR and not being extracted as text. --
I have 3 possible ways from an image-analysis perspective
Splitting
You can split the images in two part. First part is just your normal flow (load image, detect text on it). The second flow you first take the negative of the image (255 - img) and than detect text.
The two results will need to be merged afterwards.
difference filter
You can first apply a difference filter/edge detection this will high everything with a high contrast BUT can alter the shape of the letters if done to extreme or if some letters are way bigger.
contour finding + filling
Again an edge detection but now very thin and followed with an contour detection. This will redraw all letter in one color.

OpenCV Error: The operation is neither 'array op array'

I want to superimpose a given set of images of the same size (the AT&T facial images database). I have written the code to do so, which works as follows:
I have assigned the location of the images (for starting I am considering only 4 images).
imstack is used to read one image (as a base image) over which the layover (superimposition) will take place.
A for loop is run that goes through all the images and adds them to the base image (imstack). This adding is done by using the addWeighted() function with the parameters as the current image (im) and the base image (imstack) with the alpha values as 0.5 respectively.
After the loop has run till its completion (all the images are superimposed on the base image) I tried to print the updated imstack as 'compiledimg' by using the imshow().
Further I added the option to save the 'compiledimg' file by pressing 's'.
To fix the error what I have tried is to resize the image after every iteration so that the addWeighted() function receives the images with the same dimensions. First imsize (before entering the for loop) is resized as to set a firm base to the first image with the required size that I have taken as (97(rows),113(columns)).
I don't understand why the addWeighted function is not working because I am using the resize funtion to make sure that the size is kept the same after each iteration. Plus, if also tried to superimpose just two of the images and it worked perfectly fine however it does not work when I try to use the addWeighted() on the third image.
Say I used addWeighted on two images img1 and img2 and stored in img3. Now when I tried to use the addWeighted() on img3 and img4 I am getting the error. Even when I have used the resize function on img3.
Note: Initial size of the images is (97 (rows),113 (columns)) hence I am trying to keep the same image size.
import cv2
import numpy as np
import os
fnames =['~/Downloads/1.pgm','~/Downloads/2.pgm','~/Downloads/3.pgm']
imstack=cv2.imread('~/Downloads/4.pgm')
for path in fnames:
im=cv2.imread(os.path.expanduser(path))
im=cv2.resize(im,(97,113))
imstack=cv2.addWeighted(imstack,0.5,im,0.5,0)
imstack=cv2.resize(imstack,(97,113))
cv2.imshow('compiledimg',imstack)
k = cv2.waitKey(0) & 0xFF
if k == 27:
cv2.destroyAllWindows()
elif k == ord('s'):
cv2.imwrite('compiledimg.pgm',imstack)
cv2.destroyAllWindows()

How do I convert an RGB picture into graysacle using simplecv?

So working with windows, python 2.7 and simplecv I am making a live video with my webcam and want simplecv to give me a grayscale version of the video. Is there any simple way to achieve that?
I found the command
grayscale()
on the opencv page, which should do exactly that but when I run it I get the error:
NameError: name "grayscale" is not defined
I am currently using this prewritten code for object tracking but I don't know whether I should use the command I found, and where in the code I should put it, does anybody have an idea? :
print __doc__
import SimpleCV
display = SimpleCV.Display()
cam = SimpleCV.Camera()
normaldisplay = True
while display.isNotDone():
if display.mouseRight:
normaldisplay = not(normaldisplay)
print "Display Mode:", "Normal" if normaldisplay else "Segmented"
img = cam.getImage().flipHorizontal()
dist = img.colorDistance(SimpleCV.Color.BLACK).dilate(2)
segmented = dist.stretch(200,255)
blobs = segmented.findBlobs()
if blobs:
circles = blobs.filter([b.isCircle(0.2) for b in blobs])
if circles:
img.drawCircle((circles[-1].x, circles[-1].y), circles[-1].radius(),SimpleCV.Color.BLUE,3)
if normaldisplay:
img.show()
else:
segmented.show()
There are multiple ways to do this in SimpleCV.
One way has been already described, it's the toGray() method.
There's also a way you can do this with gaussian blur, which also helps to remove image noise:
from SimpleCV import *
img = Image("simplecv")
img.applyGaussianFilter(grayscale=True)
After the third line, img object contains the image with a lot less high-frequency noise, and converted to grayscale.
You may check out pyimagesearch.com who works with OpenCV, but he explains why applying Gaussian Blur is a good idea.
In simple cv theres a function called toGray() for example:
import SimpleCV as sv
img = img.jpg
sv.img.jpg.toGray()
return gimg.jpg

Categories