I am trying to extract RGB values from multiple cropped images using a single image. I want to save these RGB values into a csv file. For the same I have written the code mentioned below and the image is also attached below (color.jpg). But this code saves only the last cropped image RGB values. I want to save the RGB values for all cropped images. Could anyone suggest to me what changes I have to make for this code?
Thank you in advance
Python code:
from __future__ import with_statement
import cv2
import numpy as np
import csv
#image_path
img_path="gr.jpg"
#read image
img_raw = cv2.imread(img_path)
#select ROIs function
ROIs = cv2.selectROIs("Select Rois",img_raw)
#print rectangle points of selected roi
print(ROIs)
#Crop selected roi ffrom raw image
#roi_cropped = img_raw[int(roi[1]):int(roi[1]+roi[3]), int(roi[0]):int(roi[0]+roi[2])]
#counter to save image with different name
crop_number=0
#loop over every bounding box save in array "ROIs"
for rect in ROIs:
x1=rect[0]
y1=rect[1]
x2=rect[2]
y2=rect[3]
#crop roi from original image
img_crop=img_raw[y1:y1+y2,x1:x1+x2]
b,g,r = cv2.split(img_crop)
#Average RGB of the cropped image
B = b.mean()
G = g.mean()
R = r.mean()
#show cropped image
cv2.imshow("crop"+str(crop_number),img_crop)
#save cropped image
cv2.imwrite("crop"+str(crop_number)+".jpg",img_crop)
#Open a file to write the pixel data
with open('output_file.csv', 'w', newline='') as f_output:
csv_output = csv.writer(f_output)
csv_output.writerow(["img_name", "R", "G", "B"])
csv_output.writerow(["crop"+str(crop_number), R, G, B])
crop_number+=1
#hold window
cv2.waitKey(0)
cv2.destroyAllWindows()
[color.jpg][1]
[1]: https://i.stack.imgur.com/DpJD5.jpg
I think you just want to open for "append":
with open('output_file.csv', 'a', newline='') as f_output:
Related
I'm placeing a rotated image on top of another image of different anchor point in the same figure. However the top image partially covers the bottom image, shown below. Is there a way to remove the black border of the rotated image?
Sample codes here:
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource, show
from bokeh.layouts import column
from bokeh.models.tools import PanTool, BoxZoomTool, WheelZoomTool, \
UndoTool, RedoTool, ResetTool, SaveTool, HoverTool
import numpy as np
from collections import namedtuple
from scipy import ndimage
def make_document(doc):
p = figure(match_aspect=True)
Anchor = namedtuple('Anchor', ['x', 'y'])
img1 = np.random.rand(256, 256)
anchor1 = Anchor(x=0, y=0)
img2= np.random.rand(256, 256)
anchor2 = Anchor(x=100, y=100)
img2 = ndimage.rotate(img2, 45, reshape=True)
p.image(image=[img1], x=anchor1.x, y=anchor1.y,
dw=img1.shape[0], dh=img1.shape[1], palette="Greys256")
p.image(image=[img2], x=anchor2.x, y=anchor2.y,
dw=img2.shape[0], dh=img2.shape[1], palette="Greys256")
doc.add_root(column(p, sizing_mode='stretch_both'))
apps = {'/': make_document}
server = Server(apps)
server.start()
server.io_loop.add_callback(server.show, "/")
try:
server.io_loop.start()
except KeyboardInterrupt:
print('keyboard interruption')
print('Done')
When you rotate an image, the new empty regions (black triangles on your image) are by default initialized with 0 (check out the mode and cval options at https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.rotate.html).
If you have a value that you know for sure will never be used in an image, you can pass it as cval. Then, you should be able to manually create a color mapper that maps that value to a transparent pixel and use the mapper instead of the palette (the arg name would be color_mapper).
If you don't have such a value, then you will have to use image_rgba and just make sure that whatever cval you decide to use will result in a transparent pixel.
I am learning image manipulation as a beginner in python. My goal is to section my image into an nxn grid where each square is the average color (greyscale image) of the original, respectively. I succeeded in splitting the image, changing its pixel data and saving the new images. My problem is now stitching the image back together. I know the join function is pointing back to the original image, I had hoped that by saving over the tiles I could work around this.
This is my first time posting to stackoverflow (and I am super, super new to python), so apologies if I am not clear or if the formatting is wrong.
# Import packages
import numpy as np
from numpy import matlib
import PIL
import image_slicer
import math
import glob
from image_slicer import join
from PIL import Image
### Use PIL to import image
##img = Image.open("einstein.jpg")
# Display original image
# img.show()
##new_img = img.resize((256,256))
##new_img.save('einstein-256x256','png')
### new_img.show()
#Slice image into four pieces
tiles = image_slicer.slice("einstein.jpg", 16)
# Use glob to open every .png file with for loop
for filename in glob.glob("*.png"):
img=Image.open(filename)
pixels = img.load() # create the pixel map
pixelMap = img.load() #create the pixel map
#convert to array
arr = np.asarray(img)
#find mean
pixelMean = arr.mean(0).mean(0)[0]
# Convert mean to integer
IntMean = math.floor(pixelMean)
print(IntMean)
##pixel = pixelMap[0,0] #get the first pixel's value
##print(pixel)
# Loop for going through every pixel in image and converting it
for i in range(img.size[0]): # for every col:
for j in range(img.size[1]): # For every row
pixels[i,j] = (IntMean,IntMean,IntMean) # set the colour accordingly
# Save new monotone images
img.save(filename)
# Join new images into one
image = join(tiles)
# Save new image
image.save("einsteinJoined.jpg")
image.show()
Your question seems to be missing the error you get with your current code.
However, if I read it correctly, you will get back your original image, as was the problem in Split and Join images in Python. Similar to the answer accepted there, the solution is to change the image in each tile by ending your loop with:
tile.image = Image.open(filename)
Where tile is the tile corresponding to the file, you should loop over the tiles from the image_slicer.slice-function to do so. This is also given in answer to the question linked to.
I am a student studying about deeplearning.
I'm using tensroflow framework and make a code.
So i have a question.
I make a crop image using Pil.image.crop
but when I training the Pil.image.crop can't assign to tensor.
so How can i assign cropped image to tensor.
Plz give me a advice.
Thank you.
here is my github address
https://github.com/dldudwo0805/DeepLearningPractice
You can do it with tf.image.crop_and_resize. Here is an example:
from scipy.misc import imread
img = imread('flower.jpg')
# image placeholder
X = tf.placeholder(dtype=tf.uint8, shape=(1, 300,300,3))
# You need to set the area to crop in boxes and resize it to in crop_size
Y = tf.image.crop_and_resize(X,boxes=[[.25,.25,.75,.75]], crop_size=[100, 100], box_ind=[0] )
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
out = sess.run(Y, {X:np.expand_dims(img,0)})
When I read a colour image in OpenCV, it is showing the dimensions as 256x256x3. But I need to pass it as 3x256x256 array to my neural network. How do I change the array shape, retaining the pixel locations in BGR.
You can simply transpose the array. For an example, my picture is a 10 x 10 picture:
import numpy as np
#my picture
wrong_format = np.arange(300).reshape(10,10,3)
correct_format = wrong_format.T
If it works properly, then correct_format(0,1,1) should be equal to wrong_format(1,1,0). And we can see that it is:
correct_format(0,1,1) == wrong_format(1,1,0)
True
Is it possible to have black-and-white and color image on same window by using opencv libraray? How can I have both of these images on same window?
fraxel's answer has solved the problem with old cv interface. I would like to show it using cv2 interface, just to understand how this easy in new cv2 module. (May be it would be helpful for future visitors). Below is the code:
import cv2
import numpy as np
im = cv2.imread('kick.jpg')
img = cv2.imread('kick.jpg',0)
# Convert grayscale image to 3-channel image,so that they can be stacked together
imgc = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
both = np.hstack((im,imgc))
cv2.imshow('imgc',both)
cv2.waitKey(0)
cv2.destroyAllWindows()
And below is the output I got:
Yes it is, here is an example, expaination in the comments:
import cv
#open color and b/w images
im = cv.LoadImageM('1_tree_small.jpg')
im2 = cv.LoadImageM('1_tree_small.jpg',cv.CV_LOAD_IMAGE_GRAYSCALE)
#set up our output and b/w in rgb space arrays:
bw = cv.CreateImage((im.width,im.height), cv.IPL_DEPTH_8U, 3)
new = cv.CreateImage((im.width*2,im.height), cv.IPL_DEPTH_8U, 3)
#create a b/w image in rgb space
cv.Merge(im2, im2, im2, None, bw)
#set up and add the color image to the left half of our output image
cv.SetImageROI(new, (0,0,im.width,im.height))
cv.Add(new, im, new)
#set up and add the b/w image to the right half of output image
cv.SetImageROI(new, (im.width,0,im.width,im.height))
cv.Add(new, bw, new)
cv.ResetImageROI(new)
cv.ShowImage('double', new)
cv.SaveImage('double.jpg', new)
cv.WaitKey(0)
Its in python, but easy to convert to whatever..
Small improvement to the code with modern writing
concatenate
instead of
hstack
that is discontinued (stack can also be used)
import cv2
import numpy as np
im = cv2.imread('kick.jpg')
img = cv2.imread('kick.jpg',0)
# Convert grayscale image to 3-channel image,so that they can be stacked together
imgc = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
both = np.concatenate((im,imgc), axis=1) #1 : horz, 0 : Vert.
cv2.imshow('imgc',both)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
img = cv2.imread("image.jpg" , cv2.IMREAD_GRAYSCALE)
cv2.imshow("my image",img)
cv2.waitkey(0)
cv2.destroyAllWindow
#The image file should be in the application folder.
#The output file will be 'my image' name.
#The bottom line is to free up memory.