Hey, wrote a little C# program to demonstrate how to update the image data if the changed parameter concerns the memory of an image. We need to update the memory allocated by the driver to be able to interpret the new image data.
I posted this in the general topic because I will submit the code translated into Python and C++ later.
using System;
using Stemmer.Cvb;
using Stemmer.Cvb.Driver;
using Stemmer.Cvb.GenApi;
namespace PixelFormat
{
class Program
{
static void Main(string[] args)
{
Device device = DeviceFactory.Open("GenICam.vin");
NodeMap deviceNodeMap = device.NodeMaps[NodeMapNames.Device];
// Stream need to be stopped when setting image width or similar
// as this values are not accessible while grabbing. Thus we are using GetSnapshot rather than
// manually start the stream, get an image and then stop the stream to be able to make further changes on the image
WriteImageData(device.Stream.GetSnapshot());
Console.WriteLine("Now changing width in nodemap and updating image rect");
var oldWidth = device.DeviceImage.Width;
SetIntegerNodeMapValue(deviceNodeMap["Width"] as IntegerNode, 2000);
// As we changed parameters that directly concerns the memory for an image we have to update
// the memory allocated by the driver to be able to correctly interprete the new image data
device.ImageRect.Update(DeviceUpdateMode.UpdateDeviceImage);
WriteImageData(device.Stream.GetSnapshot());
// Set the width back to the old value
SetIntegerNodeMapValue(deviceNodeMap["Width"] as IntegerNode, oldWidth);
// keep console alive
Console.ReadKey();
}
private static void WriteImageData(Image toWriteDataFrom)
{
Console.WriteLine("Width of image: " + toWriteDataFrom.Width);
}
private static void SetIntegerNodeMapValue(IntegerNode fromNode, int toValue)
{
fromNode.Value = toValue;
Console.WriteLine("Set " + fromNode.Name + " to value: " + fromNode.Value);
}
}
}
However there is one thing worth mentioning: In case of image size changing (as in your example), the UpdateDeviceImage method can be avoided if the ChangeSize method of the IImageRect Interface is used
Hey, here is my code snippet rewritten in python. The C++ version is coming as soon as possible.
import cvb
import os
import cvb.foundation
def WriteImageData(toWriteDataFrom):
print("Width of image:", toWriteDataFrom.width)
def SetIntegerNodeMap(fromNode, toValue):
fromNode.value = toValue
print("Set", fromNode.name, " to value:", fromNode.value)
device = cvb.DeviceFactory.open(os.path.join(cvb.install_path(), "drivers", "GenICam.vin"))
deviceNodeMap = device.node_maps["Device"]
WriteImageData(device.device_image)
print("Now changing width in nodemap and updating image rect")
oldWidth = deviceNodeMap["Width"].value
SetIntegerNodeMap(deviceNodeMap["Width"], 2000)
# As we changed parameters that directly concerns the memory for an image we have to update
# the memory allocated by the driver to be able to correctly interprete the new image data
device.image_rect.update(0)
WriteImageData(device.device_image)
# Set the width back to the old value
SetIntegerNodeMap(deviceNodeMap["Width"], oldWidth)
After some delay, here is my code snipped translated into C++.
#include <iostream>
#include <cvb/device_factory.hpp>
#include <cvb/utilities/system_info.hpp>
#include <cvb/driver/stream.hpp>
#include <cvb/driver/image_rect.hpp>
using namespace std;
using namespace Cvb;
void WriteImageData(DeviceImagePtr toWriteDataFrom) {
cout << "Width of image: " << toWriteDataFrom->Width() << endl;
}
void SetIntegerNodeMapValue(shared_ptr<IntegerNode> fromNode, int toValue) {
fromNode->SetValue(toValue);
cout << "Set " << fromNode->Name() << " to value: " << fromNode->Value() << endl;
}
int main() {
auto device = DeviceFactory::Open(ExpandPath(InstallPath() + CVB_LIT("drivers/GenICam.vin")), AcquisitionStack::Vin);
auto deviceNodeMap = device->NodeMap(CVB_LIT("Device"));
WriteImageData(device->DeviceImage());
cout << "Now changing width in nodemap and updating image rect" << endl;
auto oldWidth = device->DeviceImage()->Width();
SetIntegerNodeMapValue(deviceNodeMap->Node<IntegerNode>("Width"), 2000);
// As we changed parameters that directly concerns the memory for an image we have to update
// the memory allocated by the driver to be able to correctly interprete the new image data
device->ImageRect()->Update(DeviceUpdateMode::UpdateDeviceImage);
WriteImageData(device->DeviceImage());
SetIntegerNodeMapValue(deviceNodeMap->Node<IntegerNode>("Width"), oldWidth);
}
Hi @silas
I am trying to update my device after changing few node map parameters in c++. I have opened the device as GenTL rather than Vin driver. So, when I try to update my device image from device handle, the program crashes. Any idea about this ?
Hi @keerthitheja
Could you please provide an example with as less overhead as possible so that the problem can be narrowed down. Also please add information about the line of code in which the error occurs.
Thanks
The error happens exactly in the line line_scan_device->ImageRect()->Update(DeviceUpdateMode::UpdateDeviceImage);
I commented this line because the program was crashing but I see that the device width and height are getting updated without updating the device image. Previously I was using python for another camera and I was able to update the device image. There the camera was opened as vin driver.
Here I am using the 3rd Gen Acquisition Stack. So, I am not sure if there is aother way to do this.
Hi @keerthitheja
please strip down your example to the absolute minimum for us to reproduce the error.
Alternatively you can use the example already provided by @silas here in this thread and simply change the discovery of the device to match what you do in your application.
Hi @Chris
I followed the same example given in this thread. The only difference is, I am opening my camera using GenTL Acquisition Stack and the example shown here does that with Vin Acquisition stack. Now, when I open the device with GenTL, I am able to set the node map parameters but the program crashes when calling the function device->ImageRect()->Update(DeviceUpdateMode::UpdateDeviceImage)
So, I was wondering if the device image has to be updated explicitly in case of GenTL. If so, is there any other way to do it