I want to use the open3d image screen right away without saving it as a file.
However, the 'capture_screen_image' function provided by open3d must save the image.
(http://www.open3d.org/docs/release/python_api/open3d.visualization.Visualizer.html)
This causes the problem of having to read the saved image back to 'cv2.imread'.
I wonder if there are other ways to solve this problem or other functions provided by open3d.
I would use capture_screen_float_buffer() instead of capture_screen_image().
Remember the result is a (normalised) float numpy mat, not a typical np.uint8 typed one so depending on the use, you might also need to scale it back up to 0-255 range and cast as np.uint8:
# get the image
o3d_screenshot_mat = visualizer.capture_screen_float_buffer()
# scale and convert to uint8 type
o3d_screenshot_mat = (255.0 * np.asarray(o3d_screenshot_mat)).astype(np.uint8)
# use as required
# cv2.imshow("screenshot", o3d_screenshot_mat) , PIL.Image.fromarray(o3d_screenshot_mat , "RGB"), etc.
(e.g. if you want to visualise, remap to 0-255 range, otherwise leave data as is and simply save/load as needed)
Related
I have a tif image in which its pixel are integers. I want to import it to Julia and process it further.
I used in IJulia:
using FileIO
using Images
using ImageView
path_seed = joinpath(#__DIR__,"seed.tif")
seed = load(path_seed);
When I enter seed and enter I will get an image while I want the matrix of elements.
If I use:
mat = convert(Array{Float32}, seed)
I will get a matrix but there are two problems:
1- Its entries are all float but not an integer.
2- The value of the float does not correspond to the value of integers I expect. For example, in my images there are values 0,1,2,3,4 (the image is a mask and each connected component have values of 0,1,2,3,4) but I get floats 0.0, 0.011764707, 0.015686275, 0.007843138, 0.003921569.
How can I import the image as a matrix of integers? Here is the sample image:
http://s000.tinyupload.com/index.php?file_id=21432720633236092551
When you load that file, you're seeing the effects of two of the key abstractions of JuliaImages:
every pixel is a single entry in an array (not, e.g., 3 entries if it's an RGB image)
numbers mean what they say they are. In particular, 255 ≠ 1.0.
When you load your seed.tif image, you'll note that the returned values are of type Gray{N0f8}. The Gray part means it has been interpreted as a grayscale image---had it been a color image, they might have been elements like RGB{N0f8}(1.0, 0.8, 0.4). In either case, accessing img[i,j] returns all the information about that whole pixel.
The part you're probably most concerned about is the N0f8. In most image-processing frameworks, the meaning of a number depends on its representation (e.g., https://scikit-image.org/docs/stable/user_guide/data_types.html). "White" is 255 if your numbers are encoded as UInt8, but white is 1.0 if your numbers are encoded as Float32. When you want to change the representation, you have to remember to use special conversion functions that also change the values of the pixels. In no other field of mathematics am I aware of the equality 255 == 1.0.
To stop encouraging bad mathematics, JuliaImages has gone to the trouble to define new number types that harmonize these notions. In JuliaImages, white is always 1. But to support 8-bit images, we define a new number type, N0f8, with 8 bits whose maximum value is 1. These are internally represented just like UInt8, they are just interpreted as if they have been divided by 255. Similarly, there are N0f16 for 16-bit images, and even special types like N4f12 that are useful, e.g., if you're collecting images with a 12-bit camera. This means it's possible to detect image saturation simply by looking for pixels with value 1.
Of course, sometimes you might want to look at things differently. JuliaImages supports several "views" that provide an alternative interpretation of the same bitwise data. In your case,
rawview(channelview(seed))
would return an array of UInt8 values which might be what you're expecting.
Note, however, that if you want to save an array of integers that shouldn't really be interpreted as an image, there are possibly better formats such as HDF5. Image formats are sometimes subject to compression that can corrupt the values you save. TIFF is often called lossless, but in fact it's possible to use lossy compression (https://en.wikipedia.org/wiki/TIFF).
I'm trying to get the exif data from the image.
I tried to puts
1.
puts img.orientation
#TopLeftOrientation
2.
puts img.orientation
#UndefinedOrientation
How I actually can compare the value.
if i puts img.orientation.inspect
I get some values
TopLeftOrientation=1
UndefinedOrientation=0
I want to get the value of 1 to 0 ,to perform my logic, is there a way?
Besides, I found out some resource
http://blog.choonkeat.com/weblog/2007/10/lesson-1-after-.html
when:
img["EXIF:Orientation"] == "6"
it will rotate!(90)
but in my case,i got image that is "6", but it don't need to be rotate. Any ideas?
The numbers you are seeing relate to the EXIF orientation spec:
http://sylvana.net/jpegcrop/exif_orientation.html
Those map directly to these:
http://www.imagemagick.org/RMagick/doc/constants.html#OrientationType
You could simply img.orientation.to_i to get the integer value or use a case statement to derive it based on the constants in the links above.
Sometimes EXIF data is just plain wrong. So take that with a grain of salt too, that the EXIF data for some images might be flawed.
Lastly, I'm not sure if it's of use to you, but there is an img.auto_orient! which will force the image to the proper orientation for you automatically based on the EXIF data.
I have the code for computing the histogram for hsv and yuv images. As am trying to obtain values corresponding to brightness alone, I want the 'v' channel value from hsv image and luma ('y') channel value from yuv image. this is the code I have used.
int channels[] = {0};
calcHist(&src_yuv,1,channels,Mat(),hist,1,histSize,ranges,true,false);
This sample code is for yuv. I just change {0} to {2} to obtain 'v' channel values from HSV. I am getting certain results, but am not sure if am choosing the right channels. could you please help me, to know if those numbers choose the exact channels I want to? Thanks in advance
To be absolute sure that the channel number X corresponds to the channel you are after, consult the channelSeq attribute of the IPL Image structure. If channelSeq[X] gives the name (a character) of the channel you are after, then you found it.
But, given how this attribute is documented (along other interesting ones), even if you were always using IPLImage, there is no guarantee that the information contained there would be accurate. Thus, to be absolutely sure about the channel sequence in your image you have to trust the conversion specification and remember that yourself. So, if you start with an image in BGR and convert using BGR2YUV, then you trust that the Y channel is the first one, and so on. If OpenCV ever changes BGR2YUV to mean that Y goes to the last channel, and so on, then too bad for you.
I am using OpenCV 2.4.2 and I am trying to take projections of two matrices (tmpl(32x44), subj(32x44)) along row and column. I have initialised a result matrix as rowProjectionSubj(subj.rows,1,CV_8UC1) Then I call cv::reduce(subj,rowProjectionSubj,1,CV_REDUCE_SUM,-1);
Why is this complaining about the type mismatch? I have kept the types same (by keeping dtype=-1 in cv::reduce. I get the tmpl and subj objects by doing cv::imread("image_path",0) i.e. scanning grayscale images in.
I might not be right, but after I saw this:
http://answers.opencv.org/question/3698/cvreduce-gives-unsupported-format-exception/?answer=3701#post-id-3701
and with a little experiment and using an old friend called "register math", I realised that when you add two 8-bit numbers, you need to consider a 8+1+1 bit register to store the sum because it potentially has carry output. so any result of reduce should have bigger space than the source i.e. if the source is 8-bit unsigned, it should be at least 16-bit unsigned or signed; might as well be 32-bit if it is going to be used for some product calculation and stuff...
NOTE: The destination type must be EXPLICITLY stated in the cv::reduce method. Please follow my openCV link for further information.
I have a database of images that i processed and saved as:
IplImage* database[10000];
database[0]= image1
database[1]= image2
... etc
Now I want to save this database IplImage matrix. How can i do this ? I know i can loop over all the images and save them one by one, but that is not really what i am looking for.
I read something like cvSave and cvLoad which allows me to save and load in one command but i am getting an error when i use it (cvSave("myimagedatabase.xml",&database);). Can you please guide me ?
Thank you in advance
If you don't want to save them as individual images what about using a sequence of images - also known as a movie?
See opencv cvVideoWriter, if you select 0 as the codec they will be saved uncompressed
What I gather from your question is that you are interested in saving strictly the data to some file, and then reloading back at a later point and that you would not be interested in opening the stored data in an image editing program or something like this.
First thing to consider, what are the important parts of IplImage
* depth
* height
* width
* nChannels
* imageData array
What I would do is in a loop for each IplImage make a function to write each data value into a binary file. Give the file a header noting how many images there are. Using depth, height width and nChannels you can compute the size of the imageData array. Assuming all have the same depth (IPL_DEPTH_8U for example) then this should be easy, if they vary this can get tricky.
To load the data simply read in the binary data and header information and one by one loop through all the data and create new IplImages based on that data.