I've made some modifications to https://github.com/NVIDIA/video-sdk-samples/tree/master/nvEncDXGIOutputDuplicationSample to convert the desktop image to a cv mat.
I have a dx11 2d texture and I want the 640x640 center of the texture (cropping in opencv is slow). CopySubresourceRegion (https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-copysubresourceregion) works until I pass a D3D11_BOX. When I convert it to a cv mat, it's just a black screen.
my_box.left = 1600;
my_box.top = 480;
my_box.right = 1600;
my_box.bottom = 480;
Can anyone give me a hint as to what I might be missing?
So there's a lot of x/y box options out there. I initially thought this was negatives. As in, you will define the area to not cap and you get the inverse. This is a very popular approach. This is a little goofier than that.
So lets say you want center. That's dimension(so w or h)/2-desired_box_size/2. The answer you get on each of these will be left and top. From here, you'll just add however much to get the box size. For a 3840 by 1600 monitor with a 640x640 crop your box looks like this:
my_box.front = 0;
my_box.back = 1;
my_box.left = 1600;
my_box.top = 480;
my_box.right = 2240;
my_box.bottom = -160;
Note front and back. The box is 3d as it says, but since we're working with a 2d text, we want to go 1 pixel deep. As stated in the docs, it's going to be back-front.
Related
I'm trying to remove the background of an UIImage and ended up using iOS port of MagicWand.
I was able to successfully remove the selected pixels using the flood fill algorithm by invoking the method MagickFloodfillPaintImage. However the challenge now is softening the sharp edges left by the Flood fill removal process.
I'm using the code below to remove the background.
PixelIterator* iterator = NULL;
PixelWand** pixels = NULL;
size_t x;
iterator = NewPixelRegionIterator(magick_wand, _touchCoords.x*scale, _touchCoords.y*scale, 1, 1);
pixels = PixelGetNextIteratorRow(iterator,&x);
bc_wand = pixels[0];
channel = ParseChannelOption("rgba");
status = MagickFloodfillPaintImage(magick_wand, channel, fc_wand, _tolerance, bc_wand, _touchCoords.x*scale, _touchCoords.y*scale, MagickFalse);
if (status == MagickFalse) {
ThrowWandException(magick_wand);
}
Any help would be greatly appreciated!
Sounds like you need anti-aliasing in MagickFloodfillPaintImage. However MagickFloodfillPaintImage do not support it.
But fortunately, you can use traditional multisampling technique to simulate it.
And it is quite easy:
Resize your image to a larger resolution (For example 100x100 -> 200x200)(Up sampling).
Apply MagickFloodfillPaintImage
Resize the image to the original size (Down sampling).
The quality depends on the resize ratio.
Consider this example (remove the white background):
Original algorithm would produce hard edges:
With resize, it could be much better:
I'm using the Emgu shape detection example application to detect rectangles on a given image. The dimensions of the resized image appear to impact the number of shapes detected even though the aspect ratio remains the same. Here's what I mean:
Using (400,400), actual img size == 342,400
Using (520,520), actual img size == 445,520
Why is this so? And how can the optimal value be determined?
Thanks
I replied to your post on EMGU but figured you haven't checked back but this is it. The shape detection works on the principle of thresh-holding unlikely matches, this prevents lots of false classifications. This is true for many image processing algorithms. Basically there are no perfect setting and a designer must select the most appropriate settings to produce the most desirable results. I.E. match the most objects without saying there's more than there actually is.
You will need to adjust each variable individually to see what kind of results you get. Start of with the edge detection.
Image<Gray, Byte> cannyEdges = gray.Canny(cannyThreshold, cannyThresholdLinking);
Have a look at your smaller image see what the difference is between the rectangles detected and the one that isn't. You could be missing and edge or a corner which is why it's not classified. If you are adjust cannyThreshold and observe the results, if good then keep it :) if bad :( go back to the original value. Once satisfied adjust cannyThresholdLinking and observe.
You will keep repeating this until you get a preferred image the advantage here is that you have 3 items to compare you will continue until the item that's not being recognised matches the other two.
If they are the similar, likely as it is a black and white image you'll need to go onto the Hough lines detection.
LineSegment2D[] lines = cannyEdges.HoughLinesBinary(
1, //Distance resolution in pixel-related units
Math.PI / 45.0, //Angle resolution measured in radians.
20, //threshold
30, //min Line width
10 //gap between lines
)[0]; //Get the lines from the first channel
Use the same method of adjusting one value at a time and observing the output you will hopefully find the settings you need. Never jump in with both feet and change all the values as you will never know if your improving the accuracy or not. Finally if all else fails look at the section that inspects the Hough results for a rectangle
if (angle < 80 || angle > 100)
{
isRectangle = false;
break;
}
Less variables to change as hough should do all the work for you. but still it could all work out here.
I'm sorry that there is no straight forward answer, but I hope you keep at it and solve the problem. Else you could always resize the image each time.
Cheers
Chris
Using XNA, I'm trying to make an adventure game engine that lets you make games that look like they fell out of the early 90s, like Day of the Tentacle and Sam & Max Hit the Road. Thus, I want the game to actually run at 320x240 (I know, it should probably be 320x200, but shh), but it should scale up depending on user settings.
It works kind of okay right now, but I'm running into some problems where I actually want it to look more pixellated that it currently does.
Here's what I'm doing right now:
In the game initialization:
public Game() {
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 640;
graphics.PreferredBackBufferHeight = 480;
graphics.PreferMultiSampling = false;
Scale = graphics.PreferredBackBufferWidth / 320;
}
Scale is a public static variable that I can check anytime to see how much I should scale my game relative to 320x240.
In my drawing function:
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Matrix.CreateScale(Game.Scale));
This way, everything is drawn at 320x240 and blown up to fit the current resolution (640x480 by default). And of course I do math to convert the actual coordinates of the mouse into 320x240 coordinates, and so forth.
Now, this is great and all, but now I'm getting to the point where I want to start scaling my sprites, to have them walk into the distance and so forth.
Look at the images below. The upper-left image is a piece of a screenshot from when the game is running at 640x480. The image to the right of it is how it "should" look, at 320x240. The bottom row of images is just the top row blown up to 300% (in Photoshop, not in-engine) so you can see what I'm talking about.
In the 640x480 image, you can see different "line thicknesses;" the thicker lines are how it should really look (one pixel = 2x2, because this is running at 640x480), but the thinner lines (1x1 pixel) also appear, when they shouldn't, due to scaling (see the images on the right).
Basically I'm trying to emulate a 320x240 display but blown up to any resolution using XNA, and matrix transformations aren't doing the trick. Is there any way I could go about doing this?
Render everything in the native resolution to a RenderTarget instead of the back buffer:
SpriteBatch targetBatch = new SpriteBatch(GraphicsDevice);
RenderTarget2D target = new RenderTarget2D(GraphicsDevice, 320, 240);
GraphicsDevice.SetRenderTarget(target);
//perform draw calls
Then render this target (your whole screen) to the back buffer:
//set rendering back to the back buffer
GraphicsDevice.SetRenderTarget(null);
//render target to back buffer
targetBatch.Begin();
targetBatch.Draw(target, new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height), Color.White);
targetBatch.End();
I'm new to OpenCV and just started sifting through the APIs. I intend to fetch the color, intensity and texture values of each pixel constituting the image. I was fiddling with the structure - IplImage to start with but couldn't make much progress.
Please let me know of any means to do this.
cheers
Have you tried OpenCV 2.0? They have a new C++ interface which makes things much easier. You can use their new Mat class to load images, access pixels efficiently, etc. It's much cleaner than IplImage fun. I use \doc\opencv.pdf as my reference to anything I need. It's got tutorials, and examples with the new C++ interface, etc. - enough and more to get you started.
If you have anymore specific OpenCV questions, please feel free to ask.
Here's some demo code to get you started: (I've used the cv namespace):
// Load the image (looks like MATLAB :) ? )
Mat M = imread("h:\\lena.bmp");
// Display
namedWindow("Lena",CV_WINDOW_AUTOSIZE);
imshow("Lena",M);
waitKey();
// Crop out rectangle from (100,100) of size (200,200) of the red channel
const int offset[2] = {100,100};
const int dims[2] = {200,200};
Mat Red(dims[0],dims[1],CV_8UC1);
// Read it from M into Red
uchar* lena = M.data;
for(int i=0;i<dims[0];++i)
for(int j=0;j<dims[0];++j)
{
// P = i*rows*channels + j*channels + c
Red.at<uchar>(i,j) = *(lena + (i+offset[0])*M.rows*M.channels() + (j+offset[1])*M.channels()+0);
}
//Display
namedWindow("RedRect",CV_WINDOW_AUTOSIZE);
imshow("RedRect",Red);
waitKey();
I'm using SlimDX/C# to write a Direct3D application. I configured the camera as per textbox way:
private float cameraZ = 5.0f;
camera = new Camera();
camera.FieldOfView =(float)(Math.PI/2);
camera.NearPlane = 0.5f;
camera.FarPlane = 1000.0f;
camera.Location = new Vector3(0.0f, 0.0f, cameraZ);
camera.Target = Vector3.Zero;
camera.AspectRatio = (float)InitialWidth / InitialHeight;
The drawing and rotational method are all decent Matrix.RotationYawPitchRoll and mesh.DrawSubset(0). Everything else appear normal.
My Problem is that my 3d mesh (thin square box), when look from the side, and stand vertically, it appear thicker than when it's horizontal. I've tried to change the AspectRatio to 1, it's worse. So through trial and error, I found out that it's looks much normal when the AspectRatio is around 2.6. Why is that and what could be wrong?
I've figured out the problem and answer already.
Apparently I did scale the mesh, and to match the aspect ratio, and I apply the Matrix.Scaling after Matrix.RotationYawPitchRoll. When I rotate the mesh facing forward only I realize that it looks the same no matter vertically or horizontally, the scaling is stretching it sideway no mather how I rotate. Swap the 2 matrix does fix my problem.
Thanks anyway