How do I convert Bayer to RGB using OpenCV and vice versa - visual-c++

OpenCV provided function to convert Bayer to RGB, but how to use this CV_BayerBG2BGR , and other similar function?
I used code below, but the error appears stated invalid channel number. Since I use RGB image as originalImage, anyway how this function actually works?
void main(){
// Declare and load the image
// Assume we have sample image *.png
IplImage *originalImage = cvLoadImage("bayer-image.jpg",-1);
// The image size is said to be 320X240
IplImage *bayer2RGBImage;
bayer2RGBImage = cvCreateImage(cvSize(100,100),8,3);
cvCvtColor(originalImage,bayer2RGBImage,CV_BayerBG2BGR);
//Save Convertion Image to file.
cvSaveImage("test-result.jpg",bayer2RGBImage);
//Release the memory for the images that were created.
cvReleaseImage(&originalImage);
cvReleaseImage(&bayer2RGBImage);}
Furthermore, I'd like to convert common RGB image to bayer format (let say bilinear) too, whether openCV provide this function as well?
any help would be really appreciated.
Thanks in advance.

Unfortunately OpenCV does not provide BGR to Bayer conversion. Only backward conversion is available.
If you need a conversion to Bayer format then you should implement this conversion yourself or use another library.

Related

How to make tesseract work for different kinds of images?

I am working on a digit recognition task using Tesseract and OpenCV. I did use it and came to a solution that is specific for a particular image. If I change my image I do not obtain correct results. I should change the threshold value according to the image. The steps I did was:
Cropping the image to find an appropriate region
Change image into grayscale
Using Gaussian Blur
Taking appropriate threshold
passing the image through Tesseract
So, My question is how can I make my code generic i.e. it can be used for different images without updating my code.
While working on this image I processed as`
imggray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur=cv2.GaussianBlur(imggray,(5,5), 0)
imgDil=cv2.dilate(imgBlur,np.ones((5,5),np.uint8),iterations=1)
imgEro=cv2.erode(imgDil,np.ones((5,5),np.uint8),iterations=2)
ret,imgthresh=cv2.threshold(imgEro,28,255, cv2.THRESH_BINARY )
And for this Image as
imggray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur=cv2.GaussianBlur(imggray,(5,5), 0)
imgDil=cv2.dilate(imgBlur,np.ones((5,5),np.uint8),iterations=0)
imgEro=cv2.erode(imgDil,np.ones((5,5),np.uint8),iterations=0)
ret,imgthresh=cv2.threshold(imgEro,37,255, cv2.THRESH_BINARY )
I had to change the value of iterations and the minimum threshold to obtain proper results. What can be the solution so I should not change the values?

Problems Converting Numpy/OpenCV Array Image into a Wand Image

I'm currently trying to perform a Polar to Cartesian Coordinate Image transformation, to display a raw sonar image into a 'fan-display'.
Initially I have a Numpy Array image of type np.float64, that can be seen below:
After doing some searching, I came across this StackOverflow post Inverse transform an image from Polar to Cartesian in OpenCV with a very similar problem, in which the poster seemed to have solved his/her issue by using the Python Wand library (http://docs.wand-py.org/en/0.5.9/index.html), specifically using their set of Distortion functions.
However, when I tried to use Wand and read the image in, I instead ended up with Wand getting the image below, which seems to be smaller than the original one. However, the weird thing is that img.size still gives the same size number as the original image's shape.
The code for this transformation can be seen below:
print(raw_img.shape)
wand_img = Image.from_array(raw_img.astype(np.uint8), channel_map="I") #=> (369, 256)
display(wand_img)
print("Current image size", wand_img.size) #=> "Current image size (369, 256)"
This is definitely quite problematic as Wand will automatically give the wrong 'fan image'. Is anybody familiar with this kind of problem with the Wand library previously, and if yes, may I ask what is the recommended solution to fix this issue?
If this issue isn't resolved soon I have an alternative backup of using OpenCV's cv::remap function (https://docs.opencv.org/4.1.2/da/d54/group__imgproc__transform.html#ga5bb5a1fea74ea38e1a5445ca803ff121). However the problem with this is that I'm not sure what mapping arrays (i.e. map_x and map_y) to use to perform the Polar->Cartesian transformation, as using a mapping matrix that implements the transformation equations below:
r = polar_distances(raw_img)
x = r * cos(theta)
y = r * sin(theta)
didn't seem to work and instead threw out errors from OpenCV as well.
Any kind of help and insight into this issue is greatly appreciated. Thank you!
- NickS
EDIT I've tried on another image example as well, and it still shows a similar problem. So first, I imported the image into Python using OpenCV, using these lines of code:
import matplotlib.pyplot as plt
from wand.image import Image
from wand.display import display
import cv2
img = cv2.imread("Test_Img.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure()
plt.imshow(img_rgb)
plt.show()
which showed the following display as a result:
However, as I continued and tried to open the img_rgb object with Wand, using the code below:
wand_img = Image.from_array(img_rgb)
display(img_rgb)
I'm getting the following result instead.
I tried to open the image using wand.image.Image() on the file directly, which is able to display the image correctly when using display() function, so I believe that there isn't anything wrong with the wand library installation on the system.
Is there a missing step that I required to convert the numpy into Wand Image that I'm missing? If so, what would it be and what is the suggested method to do so?
Please do keep in mind that I'm stressing the conversion of Numpy to Wand Image quite crucial, the raw sonar images are stored as binary data, thus the required use of Numpy to convert them to proper images.
Is there a missing step that I required to convert the numpy into Wand Image that I'm missing?
No, but there is a bug in Wand's Numpy implementation in Wand 0.5.x. The shape of OpenCV's ndarray is (ROWS, COLUMNS, CHANNELS), but Wand's ndarray is (WIDTH, HEIGHT, CHANNELS). I believe this has been fixed for the future 0.6.x releases.
If so, what would it be and what is the suggested method to do so?
Swap the values in img_rgb.shape before passing to Wand.
img_rgb.shape = (img_rgb.shape[1], img_rgb.shape[0], img_rgb.shape[2],)
with Image.from_array(img_rgb) as img:
display(img)

Converting PDF/SVG to PNG with antialias off using Magick++

I've tried to convert a SVG file to PNG with antialiasing off in Magick++ but I wasn't successful. But I was able to convert the SVG file to PDF with another program and the use the ImageMagick convert command to convert the PDF file to PNG.
How can I use ImageMagick to do it? The command I use for converting PDF to PNG is this:
convert +antialias -interpolate Nearest -filter point -resize 1000x1000 "img.pdf" PNG24:"filter.png"
Is there any way to use Magick++ to do that or better, convert SVG to PNG directly with antialiasing off?
Thanks in advance.
Edit:
The answer given in this post doesn't work for me. Possible because I'm using a colored SVG instead of 1-bit alpha channel. Also I mentioned in my question that I'm also looking for a way to do this in Magick++.
Magick++ has the Magick::Image::textAntiAlias & Magick::Image::strokeAntiAlias methods available, but they would only be useful if your parsing the SVG and rebuilding the image (i.e. roll-your-own SVG engine) one SVG element at a time.
As #ccprog pointed out in the comments; once the decoder utility rasters the vectors, the damage is done & setting the flags would not have an effect on the resulting resize.
Without seeing the SVG, I can only speculate what the problem is. I would suggest setting the document size before reading the SVG content.
For example, read the image at a smaller size than resample up.
Magick::Image img;
img.size(Magick::Geometry(100, 100)); // Decode to a small context
img.read("input.svg");
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.resize(Magick::Geometry(600, 600));
img.write("PNG24:output#100x100.png");
Or render at larger size then the finial image.
Magick::Image img;
img.size(Magick::Geometry(1000, 1000)); // Decode to a larger context
img.read("input.svg");
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.resize(Magick::Geometry(600, 600));
img.write("PNG24:output#1000x1000.png");
Update from comments
For Postscript (PDF) & True-Type antialiasing, you would set Magick::Image::textAntiAlias (or Magick::Image::antiAlias if using IM6) to false. Just ensure that the density is set to allow any overhead.
Magick::Image img;
img.density(Magick::Point(300));
if (MagickLibVersion < 0x700) {
img.antiAlias(false);
} else {
img.textAntiAlias(false);
}
img.interpolate(Magick::NearestInterpolatePixel);
img.filterType(Magick::PointFilter);
img.read("input.pdf");
img.resize(Magick::Geometry(1000, 1000));
img.write("PNG24:output.png");

How to convert YUV422 image to JPEG using ffmpeg's libraries?

I'm trying to convert a YUV422 image (YUV422_8_UYVY, unsigned ,unpacked, 16bpp) in to jpeg using ffmpeg's ,this is Code which I am following
Image size: 2448x2050
Original YUV Image: not able to upload as the format is YUV
(Original Image Decodec by ffmpeg command prompt)
Image:This is original Image
Image size: 2448x2050
reconstruct Image:Reconstruct Image through above Code
so the reconstruct image is not as the original image
my format is UYVY whereas supported format is AV_PIX_FMT_YUVJ420P
so what should be the correct format for UYVY input image...?
pCodecCtx->pix_fmt=AV_PIX_FMT_?????
if i use pCodecCtx->pix_fmt=AV_PIX_FMT_UYVY422;
i got an arrer saying
[mjpeg # 00c0b2a0] specified pixel format uyvy422 is invalid or not supported
You say the image format is "unpacked" (??), but at the same time you call it YUV422_8_UYVY, which suggests it's packed (i.e. not planar). The output you're getting suggests that it's packed.
FFmpeg's image encoders, in general, do not support packed input. You first need to make it planar. You have two options:
convert it to planar YUV-4:2:2 (AV_PIX_FMT_YUVJ422P) and input that into the encoder;
convert it to planar YUV-4:2:0 (AV_PIX_FMT_YUVJ420P) and input that into the encoder.
The first will preserve chroma subsampling (better quality), but the second will have better downstream support (in other applications, to decode the image). To convert the image, you use libswscale. The output image from that conversion can be input into the FFmpeg encoder.

how to correct the orientation of the image with ITK-VTK

I am a beginner in VTK ITK, I am trying to read a DICOM series with ITK and display with VTK but I had pictures upside down, I tried to read a single image (JPG) with ITK and visualuser with VTK it is the same problem, so I had the idea of ​​treating the image on photoshop ie I applied to the original image rotation (vertical symmetry of the work area) and I did the reading with ITK and display with VTK, the image is displayed in the correct orientation, infact ITK keeps the orientation of the image, but the problem is at VTK, it is which displays the image upside down, I searched all over the internet I have not found a solution or a method or not even an idea, I encountered the same problem in many forums but there is no response, I count on your help, I can not apply any image processing to find a solution to this problem.
Please Help! thank you in advance
Ideally you should re-orient your camera in VTK so that it is suited for medical image visualization. (The default camera in VTK uses the computer graphics conventions).
If you want a quick hack, you can copy-paste the following code in ITK:
FlipFilterType::Pointer flipperImage = FlipFilterType::New();
bool flipAxes[3] = { false, true, false };
flipperImage = FlipFilterType::New();
flipperImage->SetFlipAxes(flipAxes);
flipperImage->SetInput( image );
flipperImage->Update();
I use a rapid way to set the orientation:
imageActor->SetOrientation(180,0,0);
No need to add filter.
Here's an example of how I would do it. I'm not sure what classes you are using, so I cannot be specific.
vtkSmartPointer<vtkImageData> result = vtkSmartPointer<vtkIMageData>::New();
result->DeepCopy(YourImage); //DeepCopy your image to result
rImage->Update();
double val;
int i = 0;
for(vtkIdType f = result->GetNumberOfPoints()-1; f > -1; f--)
{
val = YourImage->GetPointData()->GetScalars()->GetTuple1(f);
result->GetPointData()->GetScalars->SetTuple1(i,val);
i++;
}
result->Update();
//Now Visualize your image

Resources