I tried converting tiff images into numpy arrays. I used PIL to open it and then passed it to np.array()
img1 = Image.open(img1_path)
temp = np.array(img1)
print('TYPE:' + str(type(temp)))
print(temp)
Here's the output:
TYPE:<class 'numpy.ndarray'>
[[1342 1435 1428 ... 1165 1168 1170]
[1407 1376 1267 ... 1175 1148 1166]
[1336 1454 1434 ... 1174 1159 1169]
...
[1204 1201 1302 ... 1115 1131 1126]
[1202 1246 1305 ... 1125 1129 1118]
[1285 1319 1319 ... 1127 1124 1127]]
The shape of array is - (858, 557)
When we convert any image into numpy array, we usually see values ranging from 1-255, but how are we seeing values so much higher than that? I don't know a lot about tiff files. And I can't understand this concept. Any help or resources would be appreciated. Thank you.
Related
I have a plotted spectral curve in google sheets. All points are real coordinates. As you can see, data is not provided for the slope below 614nm. I would like to extend the slope beyond the supplied data, so that it reaches 0. In a mathematically relevant way to follow the trajectory it was taking from when the slope started. Someone mentioned to me I would have to potentially use a linear regression? I'm not sure what that is. How would I go about extending this slope relevant to it's defined trajectory down to 0 in google sheets?
Here's the data
x-axis:
614
616
618
620
622
624
626
628
630
632
634
636
638
640
642
644
646
648
650
652
654
656
658
660
662
664
666
668
670
672
674
676
678
680
682
684
686
688
690
692
694
696
698
700
702
704
706
708
710
712
714
716
718
720
722
724
726
728
730
y-axis:
0.7101
0.7863
0.8623
0.9345
1.0029
1.069
1.1317
1.1898
1.2424
1.289
1.3303
1.3667
1.3985
1.4261
1.4499
1.47
1.4867
1.5005
1.5118
1.5206
1.5273
1.532
1.5348
1.5359
1.5355
1.5336
1.5305
1.5263
1.5212
1.5151
1.5079
1.4994
1.4892
1.4771
1.4631
1.448
1.4332
1.4197
1.4088
1.4015
1.3965
1.3926
1.388
1.3813
1.3714
1.359
1.345
1.3305
1.3163
1.303
1.2904
1.2781
1.2656
1.2526
1.2387
1.2242
1.2091
1.1937
1.1782
Thanks
I understand that you want The curve should be increased beyond the given data in a mathematically sound fashion until it approaches 0, In what follows, I'm going to show how it's done with the last 2 data points which make the filled data linear it might help, like this: take a look at this Sheet.
We need to
1 - Paste this SEQUENCE function formula in C3 to get the order of input
=SEQUENCE(COUNTA(B3:B),1,1,1)
2 - SORT the the input by pasting this formula in E3.
=SORT(A3:C61,3,0)
3 - In F62 after the last line of the sorted data paste this TREND function that Fits an ideal linear trend using the least squares approach to incomplete data about a linear trend and/or makes additional value predictions..
=TREND(F60:F61,E60:E61,E62:E101)
TREND takes
'known_data_y' set to F60:F61
'[known_data_x]' set to E61,E62 those are the 2 data point
[known_data_x] set to E62:E101, we get it by pasting E62:E101 after the last line of the sorted data in "x-axis:" in output table cell E62
4 - To see the newly genrated data in the red curve we need a new column that start from K62 till the very bottom of the data "y-axis:" in output table cell K62, by pasting this ArrayFormula in K62.
=ArrayFormula(E62:G101)
5 - Add a Serie in tne chart in chart editor > setup > Series > Add Serie.
I know the opencv got a BGR order, but in my experiment, not only the order but also the values are totally messed
import cv2 as cv
import tifffile as tiff
import skimage.io
img_path = r"C:\test\pics\t100r50s16_1_19.tif"
c = cv.imread(img_path,cv.IMREAD_UNCHANGED)
t = tiff.imread(img_path)
s = skimage.io.imread(img_path)
print("c:", c.shape, "t:", t.shape, "s:", s.shape)
print("c:", c.dtype, "t:", t.dtype, "s:", s.dtype)
print(c[0, 0], c[1023, 0], c[0, 1023], c[1023, 1023])
print(t[0, 0], t[1023, 0], t[0, 1023], t[1023, 1023])
print(s[0, 0], s[1023, 0], s[0, 1023], s[1023, 1023])
print(c.sum())
print(t.sum())
print(s.sum())
And the outputs like this:
c: (1024, 1024, 4) t: (1024, 1024, 4) s: (1024, 1024, 4)
c: uint8 t: uint8 s: uint8
[ 50 63 56 182] [131 137 140 193] [29 28 27 94] [123 130 134 190]
[ 79 88 70 182] [185 181 173 193] [74 77 80 94] [180 174 165 190]
[ 79 88 70 182] [185 181 173 193] [74 77 80 94] [180 174 165 190]
# Here seems that opencv only read the alpha channel right,
# the values of first three channels are much different than other package
539623146
659997127
659997127
The image i use can be download here. So, here is my question, how open cv handle 4 channel tiff file? Because when i test on 3-channel image, everything looks alright.
I don't buy it for a minute that there is a rounding error or some error related to JPEG decoding like the linked article suggests.
Firstly because your image is integer, specifically uint8 so there is no rounding of floats, and secondly because the compression of your TIF image is not JPEG - in fact there is no compression. You can see that for yourself if you use ImageMagick and do:
identify -verbose a.tif
or if you use tiffinfo that ships with libtiff, like this:
tiffinfo -v a.tif
So, I did some experiments by generating sample images with ImageMagick like this:
# Make 8x8 pixel TIF full of RGBA(64,128,192) with full opacity
convert -depth 8 -size 8x8 xc:"rgba(64,128,192,1)" a.tif
# Make 8x8 pixel TIFF with 4 rows per strip
convert -depth 8 -define tiff:rows-per-strip=4 -size 8x8 xc:"rgba(64,128,192,1)" a.tif
And OpenCV was able to read all those correctly, however, when I did the following it went wrong.
# Make 8x8 pixel TIFF with RGB(64,128,192) with 50% opacity
convert -depth 8 -define tiff:rows-per-strip=1 -size 8x8 xc:"rgba(64,128,192,0.5)" a.tif
And the values came out in OpenCV as 32, 64, 96 - yes, exactly HALF the correct values - like OpenCV is pre-multiplying the alpha. So I tried with an opacity of 25% and the values came out at 1/4 of the correct ones. So, I suspect there is a bug in OpenCV that premultiplies the alpha.
If you look at your values, you will see that tifffile and skimage read the first pixel as:
[ 79 88 70 182 ]
if you look at the alpha of that pixel, it is 0.713725 (182/255), and if you multiply each of those values by that, you will get:
[ 50 63 56 182 ]
which is exactly what OpenCV did.
As a workaround, I guess you could divide by the alpha to scale correctly.
In case the argument is that OpenCV intentionally pre-multiplies the alpha, then that begs the question why it does that for TIFF files but NOT for PNG files:
# Create 8x8 PNG image full of rgb(64,128,192) with alpha=0.5
convert -depth 8 size 8x8 xc:"rgba(64,128,192,0.5)" a.png
Check with OpenCV:
import cv2
c = cv2.imread('a.png',cv2.IMREAD_UNCHANGED)
In [4]: c.shape
Out[4]: (8, 8, 4)
In [5]: c
Out[5]:
array([[[192, 128, 64, 128],
[192, 128, 64, 128],
...
...
In case anyone thinks that the values in the TIF file are as OpenCV reports them, I can only say that I wrote rgb(64,128,192) at 50% opacity and I tested each of the following and found that they all agree, with the sole exception of OpenCV that that is exactly what the file contains:
ImageMagick v7
libvips v8
Adobe Photoshop CC 2017
PIL/Pillow v5.2.0
GIMP v2.8
scikit-image v0.14
I've run into a bit of a delima. I've been doing some 3D scanning and would like to convert .xyz file attained from the scanning process to LibSVM format.
the .xyz file would look like this:
31 423 578
34 423 582
42 423 621
43 423 650
47 423 668
48 423 677
80 423 670
84 423 589
86 423 602
88 404 553
89 403 583
89 404 664
90 393 673
90 396 563
90 397 607
90 403 624
90 404 666
91 409 517
91 411 579
And LibSVM format is like this:
<label> <index1>:<value1> <index2>:<value2> ...
What is to be considered before going about this process? What exactly would my label and index value(s) be? I'm sure value1 would equal the x coordinate. (Please correct me if I'm wrong).
Any demonstration code to give me a gist of the process would certain be appreciated. But words are great.
We created custom font for our application with custom Emoji symbols. Sometimes app crashes with following stacktrace (always the same):
0 libsystem_platform.dylib 0x38b8d486 _platform_memmove$VARIANT$Swift + 102
1 CoreFoundation 0x2d8f7575 CFDataGetBytes + 237
2 ImageIO 0x2e6e1e8f CGImageReadGetBytesAtOffset + 299
3 ImageIO 0x2e6e1d59 CGImageReadSessionGetBytes + 29
4 ImageIO 0x2e825973 read_fn + 23
5 ImageIO 0x2e6e1cb1 png_read_sig + 45
6 ImageIO 0x2e6e1935 _cg_png_read_info + 33
7 ImageIO 0x2e6ea15b copyImageBlockSetPNG + 1123
8 ImageIO 0x2e6e9779 ImageProviderCopyImageBlockSetCallback + 529
9 CoreGraphics 0x2da2647d CGImageProviderCopyImageBlockSetWithOptions + 137
10 CoreGraphics 0x2da492f7 CGImageProviderCopyImageBlockSet + 39
11 CoreGraphics 0x2da2614f img_blocks_create + 411
12 CoreGraphics 0x2da492bb img_blocks_extent + 63
13 CoreGraphics 0x2da49271 img_interpolate_extent + 109
14 CoreGraphics 0x2da1a12d img_data_lock + 4421
15 CoreGraphics 0x2da187e9 CGSImageDataLock + 89
16 libRIP.A.dylib 0x2dd65da7 ripc_AcquireImage + 99
17 libRIP.A.dylib 0x2dd65131 ripc_DrawImage + 601
18 CoreGraphics 0x2da186fb CGContextDelegateDrawImage + 51
19 CoreGraphics 0x2da18581 CGContextDrawImage + 285
20 CoreText 0x2e0a43db TCGImageData::DrawInRect(CGRect) const + 311
21 CoreText 0x2e062299 CTFontDrawGlyphsWithAdvances + 705
22 CoreText 0x2e070d55 TRun::DrawGlyphs(CGContext*, CFRange) const + 241
23 CoreText 0x2e070c25 TLine::DrawGlyphs(CGContext*) const + 157
24 UIFoundation 0x358860df __NSStringDrawingEngine + 10151
25 UIFoundation 0x35883863 -[NSString(NSExtendedStringDrawing) drawWithRect:options:attributes:context:] + 151
26 UIKit 0x301e72c9 -[UILabel _drawTextInRect:baselineCalculationOnly:] + 4225
27 UIKit 0x3024d709 -[UILabel drawTextInRect:] + 501
28 UIKit 0x3024d50b -[UILabel drawRect:] + 79
29 UIKit 0x3024d4a9 -[UIView(CALayerDelegate) drawLayer:inContext:] + 373
30 QuartzCore 0x2fe79189 -[CALayer drawInContext:] + 101
I don't know is it possible to get help for such situation, but maybe someone from Apple could give advice what is wrong with font. I could provide font if needed.
Unfortunately this is not a conclusive answer, but it's too long for a comment so I guess feel free to downvote, those who do that sort of thing. But I hope you won't, because I think this could be useful information.
I took a pretty deep look into this font, which uses the newly-defined 'sbix' table, just as Apple's Color Emoji font does, to store color images (PNGs in this case) for icons. I went through the data table and dumped out each of the icons to PNG files and everything appeared to be okay (what it means is: the 'sbix' table itself seems to follow the specification, and the resulting PNG images do not appear to be corrupted and are in fact rather amusing!).
However: there are some characteristics of this font compared to the Apple Color Emoji font that I find a bit odd. Apple's font has 7 "strikes" (sizes): 20, 32, 40, 48, 64, 96, 160, whereas yours has only one: 285. My understanding is that the system is supposed to up/down-scale when asked for a font size that doesn't exist in the font (e.g. you call for 50, it scales 285 down to 50), but given that Apple's maximum strike size is 160 it makes me wonder whether there is some unspecified upper size limit for fonts. Another thing I noticed is that the PNG data is 256 pixels wide and I'm not sure how that's supposed to relate to the 285 size (maybe padding?).
Looking at the stack trace, it looks like it's getting the image data out of the font, but failing somewhere during the actual rendering of the image.
I'm not sure what you used to create this font, but something you might try if you can is to scale the images such that your strike size is 160, matching Apple's maximum, and see what happens there. Sorry I could not be of more help, but I hope this at least gives you something to investigate further.
I am brand new to programming in general, and am working on a project for which I need to capture images from my webcam (possibly using OpenCV), and save the images as pgm files.
What's the simplest way to do this? Willow Garage provides this code for image capturing:
http://opencv.willowgarage.com/wiki/CameraCapture
Using this code as a base, how might I modify it to:
capture an image from the live cam every 2 seconds
save the images to a folder in pgm format
Thanks so much for any help you can provide!
First of all, please use newer site - opencv.org. Using outdated references leads to chain effect, when new users see old references, read old docs and post old links again.
There's actually no reason to use old C API. Instead, you can use newer C++ interface, which, among other things, handles capturing video gracefully. Here's shortened version of example from docs on VideoCapture:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
// do any processing
imwrite("path/to/image.png", frame);
if(waitKey(30) >= 0) break; // you can increase delay to 2 seconds here
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Also, if you are new to programming, consider using Python interface to OpenCV - cv2 module. Python is often considered simpler than C++, and using it you can play around with OpenCV functions right in an interactive console. Capturing video with cv2 looks something like this (adopted code from here):
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# do what you want with frame
# and then save to file
cv2.imwrite('path/to/image.png', frame)
if cv2.waitKey(30) & 0xFF == ord('q'): # you can increase delay to 2 seconds here
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Since ffriend's answer is only partially true, I'll add some more to it (in C++). The author of this question asks explicitly for exporting to PGM (PXM file format that stores each pixel in 8 bits) and not PNG (as ffriend describes in his/her reply). The main issue here is that the official documentation for imwrite is omho not clear about this matter at all:
For PPM, PGM, or PBM, it can be a binary format flag ( CV_IMWRITE_PXM_BINARY ), 0 or 1. Default value is 1.
If we read the sentence in normal English, we have a list of options: CV_IMWRITE_PXM_BINARY, 0 or 1. There is no mention that those can and actually are supposed to be combined! I had to experiment a little bit (I also needed to store 8-bit images for my project) and finally got to the desired solution:
std::vector<int> compression_params; // Stores the compression parameters
compression_params.push_back(CV_IMWRITE_PXM_BINARY); // Set to PXM compression
compression_params.push_back(0); // Set type of PXM in our case PGM
const std::string imageFilename = "myPGM.pgm"; // Some file name - C++ requires an std::string
cv::imwrite(imageFilename, myImageMatrix, compression_params); // Write matrix to file
My investigation was also fueled by this question where the author was (maybe still is) struggling with the very same issue and also by some basic information on the PXM format, which you can find here.
The result (only part of the image) is displayed below:
P2
32 100
255
121 237 26 102 88 143 67 224 160 164 238 8 119 195 138 16 176 244 72 106 72 211 168 45 250 161 37 1 96 130 74 8
126 122 227 86 106 120 102 150 185 218 164 232 111 230 207 191 39 222 236 78 137 71 174 96 146 122 117 175 34 245 6 125
124 121 241 67 225 203 118 209 227 168 175 40 90 19 197 190 40 254 68 90 88 242 136 32 123 201 37 35 99 179 198 163
97 161 129 35 48 140 234 237 98 73 105 77 211 234 88 176 152 12 68 93 159 184 238 5 172 252 38 68 200 130 194 216
160 188 21 53 16 79 71 54 124 234 34 92 246 49 0 17 145 102 72 42 105 252 81 63 161 146 81 16 72 104 66 41
189 100 252 37 13 91 71 40 123 246 33 157 67 96 71 59 17 196 96 110 109 116 253 30 42 203 69 53 97 188 90 68
101 36 84 5 41 59 80 8 107 160 168 9 194 8 71 55 152 132 232 102 12 96 213 24 134 208 1 55 64 43 74 22
92 77 30 44 139 96 70 152 160 146 142 8 87 243 11 91 49 196 104 250 72 67 159 44 240 225 69 29 34 115 42 2
109 176 145 90 137 172 65 25 162 57 169 92 214 211 72 94 149 20 104 56 27 67 218 17 203 182 5 124 138 2 130 48
121 225 25 106 89 76 69 189 34 25 173 8 114 83 72 52 145 154 64 40 91 2 251 53 251 237 20 124 82 2 194 42 ...
Which is exactly what is required in this case. You can see the "P2" marking at the top and also the values are clearly from 0 to 255, which is exactly 8 bits per pixel.
Read most of the answers but none of them could satisfy my requirement. Here's how I implemented it.
This program will use webcam as a camera and clicks picture when you press 'c' - we can change the condition, then make it to click pictures automatically after certain interval
# Created on Sun Aug 12 12:29:05 2018
# #author: CodersMine
import cv2
video_path = 0 # 0 internal cam, 1 external webcam
cap = cv2.VideoCapture(video_path)
img_ctr = 0 # To Generate File Names
while(True):
ret, frame = cap.read()
cv2.imshow("imshow",frame)
key = cv2.waitKey(1)
if key==ord('q'): # Quit
break
if key==ord('c'): # Capture
cv2.imshow("Captured",frame)
flag = cv2.imwrite(f"image{img_ctr}.png", frame)
print(f"Image Written {flag}")
img_ctr += 1
# Release the Camera
cap.release()
cv2.destroyAllWindows()
If you don't need superaccurate 2seconds then simply put a sleep(2) or Sleep(2000) in the while(1) loop to wait fro 2seconds before each grab,
Write images with cvSaveImage() just put the extention .pgm on the filename and it will use pgm.
I believe that the format is chosen from the extension of the filename - so assuming your opencv lib's are linked against the appropriate libs you can do something like: (this is from memory, might not be correct.)
CvCapture* capture = cvCaptureFromCam(0);
IplImage* frame = cvQueryFrame(capture);
while (1) {
frame = cvQueryFrame(capture);
cvSaveImage("foo.pgm", &frame);
sleep(2);
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);