Hello,
I am making a program by Python, I wonder how I can have access to the information I could get from Cvb.Image.GetImageVPA(image, 0, out pnt, out pnt2)
when I was codding in C#.
Thank you in advance
Hello,
I am making a program by Python, I wonder how I can have access to the information I could get from Cvb.Image.GetImageVPA(image, 0, out pnt, out pnt2)
when I was codding in C#.
Thank you in advance
Hi @Fatemeh
The pixel access in CvbPy is as follows:
1 # CVBpy Example Script
2 #
3 # 1. Loads an image from file.
4 # 2. Converts it to a numpy array without copying
5 # 3. Modify pixel values through numpy
6 # 4. Save the image.
7 #
8 # Requires: numpy
9
10 import os
11 import cvb
12
13 image = cvb.Image(os.path.join(cvb.install_path(), "tutorial", "Clara.bmp"))
14
15 # copy=Fasle is default, but just a request
16 np_array = cvb.as_array(image, copy=False)
17
18 if np_array.flags["OWNDATA"]:
19 raise RuntimeError("cannot map to numpy array")
20
21 # pixel access
22 print("Modifining pixel data via numpy array.")
23 np_array[83 : 108, 48 : 157] = 0
24
25 print("Saving: ./ClaraUnknown.bmp")
26 image.save("ClaraUnknown.bmp")
27
Thanks for your answer.
This solution did not give me the data I needed, I need exactly the equivanet of Cvb.Image.GetImageVPA() in Python.
The data that I read from camera is in nonlinear format.
Hi @Fatemeh
There is no VPAT functionality in Cvpy. It is not possible to convert all C# implementation and functionality exactly into Python. Knowing pixel coordinate you can also get its value using get_pixel function:
List[float] get_pixel (self, cvb.Point2D position )
Please let us know what exactly you plan to do.
Hi @Fatemeh
the information returned by GetImageVPA
is only usable when working with pointers (basically the VPAT is a set of two tables with offsets that can be added to a base pointer in order to determine the address of a pixel (x, y):
To actually make use of the pointer p_{pixel} the language you are working with must support the notion of pointers. Python does not directly support the notion of pointers, making it hard and very error-prone to actually work with VPAT information, which is why we never ported GetImageVPA
into that realm.
If the fact that you are dealing with a nonlinear VPAT is causing issues, you might want to make a deep copy of the image: The VPAT of an image that is the result of a deep copy of a image is always linear.
Thank you @MandanaS and @illusive
Let me explain more, I have this code in C#
image = _stream.Wait(out status);
var buffer = new long[_width];
IntPtr pnt;
IntPtr pnt2;
bool success = Cvb.Image.GetImageVPA(new SharedImg(image.Handle), 0, out pnt, out pnt2);
Marshal.Copy(pnt, buffer, 0, buffer.Length);
although my image data at first is 8bpp
I could have access to 64 bpp data by using the code above
I want to do exactly the same thing in Python, because I need information in 64 bpp format.
Your image has only 1 byte information I do not know why you want to convert it to 8 bytes. You can do this conversion in python as it shows below:
np_array_64 = np_array.astype(int64,copy=False)
@MandanaS As you see my numbers are greater than 255 but in python the max is 255.
I need the rest of information so I need a real value in 8 bytes, not just converting a 1 byte number to 8 bytes.
It shows 1 byte, but we read the rest of information in C# in 8 bytes
The screenshot from your code shows that the actual image pixel hat one byte information that means in original image each pixel can have a maximum decimal value of 255. by defining an array with the type of long (int64) you are trying to convert one byte Information to 8 byte and end up with strange pixel values.
Hi @Fatemeh,
I am sorry, but the code you posted may potentially produce undefined behavior. If it does what you expected, then this is by chance more than anything else. Your snippet was:
image = _stream.Wait(out status);
var buffer = new long[_width];
IntPtr pnt;
IntPtr pnt2;
bool success = Cvb.Image.GetImageVPA(new SharedImg(image.Handle), 0, out pnt, out pnt2);
Marshal.Copy(pnt, buffer, 0, buffer.Length);
in Marshal.Copy(pnt, buffer, 0, buffer.Length);
all you do is use the base pointer returned by the GetImageVPA
call. This pointer is not guaranteed to point to the address of pixel (0, 0). The address of pixel (0, 0) must be calculated as
Cvb.Image.VPAEntry* pVPAT = (Cvb.Image.VPAEntry*)pnt2[0].ToPointer();
var pPixel = (byte*)pBase[0] + pVPAT[0][y].YEntry.ToInt64() + pVPAT[0][x].XEntry.ToInt64()
Only if XEntry
and YEntry
in the above code happen to be zero (which is for example not the case for a loaded bitmap file) will the Marshal.Copy
actually copy the first line. If, on the other hand, XEntry
and YEntry
are both non-zero, then the Marshal.Copy
will sooner or later raise an access violation.
In you case, the image is linearly arranged and 1 pixel high, so XEntry
and YEntry
are very likely to be zero, but it would be good to safeguard versus the possibility that they are not.
As for the original task and question:
get_pixel
member of the image plane you are working on. This returns the pixel values as float values. Cast them to int, then combine 8 of them (upshifted by 0, 8, 16, 24, 32, 40, 48, 56) by adding their values and you will have the 64 bit representation:pixels = [None] * 8
for x in range(0, 7):
pixels[x] = int(myImg.planes[0].get_pixel(Point2D(x, 0)))
val64 = pixels[0] + pixels[1] << 8 + pixels[2] << 16 + pixels[3] << 24 ... + pixels[7] << 56
Python seamlessly switches from plain 64 bit integers to long (unbound) integers if the range [-sys.maxsize - 1 ... sys.maxsize]
is exceeded - which will most likely be the case for your calculations. So altogether the performance will probably not be great.