So Im trying to write a single character using putText() on top of an image to fit into a 25x25 box but the text is too small to render, it just looks like a blob of whatever color I choose the text to be. Is there any way to create small, readable text to overlay onto an image with OpenCV?
Here is an example using both putText() and also loading a character from a file created in Photoshop or GIMP.
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
using namespace cv;
using namespace std;
int
main(int argc,char*argv[])
{
// Make a 3 channel image
cv::Mat main(200,300,CV_8UC3);
// Fill entire image with magenta
main = cv::Scalar(255,0,255);
// Load a character "M" from a file and overlay
Mat txt = cv::imread("M.png",-CV_LOAD_IMAGE_ANYDEPTH);
txt.copyTo(main(cv::Rect(80,120,txt.cols,txt.rows)));
// Now use puttext() to do a white S
int fontFace = FONT_HERSHEY_COMPLEX_SMALL;
double fontScale=1.5;
string text="S";
putText(main,"S",Point(60,100),fontFace,fontScale,Scalar(255,255,255));
// Save to disk
imwrite("result.png",main);
}
Here's the M.png file:
Here's the result:
I also notice that the anti-aliased fonts (on the right side in image below) look somewhat easier to read:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
using namespace cv;
using namespace std;
int
main(int argc,char*argv[])
{
// Make a 3 channel image
cv::Mat main(280,800,CV_8UC3);
// Fill entire image with magenta
main = cv::Scalar(255,0,255);
double fontScale=1.5;
int thickness=1;
int x=10,y=40;
putText(main,"Simplex",Point(x,y),CV_FONT_HERSHEY_SIMPLEX,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Simplex AA",Point(x+400,y),CV_FONT_HERSHEY_SIMPLEX,fontScale,Scalar(255,255,255),thickness,CV_AA);
y+=40;
putText(main,"Plain",Point(x,y),CV_FONT_HERSHEY_PLAIN,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Plain AA",Point(x+400,y),CV_FONT_HERSHEY_PLAIN,fontScale,Scalar(255,255,255),thickness,CV_AA);
y+=40;
putText(main,"Duplex",Point(x,y),CV_FONT_HERSHEY_DUPLEX,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Duplex AA",Point(x+400,y),CV_FONT_HERSHEY_DUPLEX,fontScale,Scalar(255,255,255),thickness,CV_AA);
y+=40;
putText(main,"Complex",Point(x,y),CV_FONT_HERSHEY_COMPLEX,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Complex AA",Point(x+400,y),CV_FONT_HERSHEY_COMPLEX,fontScale,Scalar(255,255,255),thickness,CV_AA);
y+=40;
putText(main,"Triplex",Point(x,y),CV_FONT_HERSHEY_TRIPLEX,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Triplex AA",Point(x+400,y),CV_FONT_HERSHEY_TRIPLEX,fontScale,Scalar(255,255,255),thickness,CV_AA);
y+=40;
putText(main,"Script",Point(x,y),CV_FONT_HERSHEY_SCRIPT_SIMPLEX,fontScale,Scalar(255,255,255),thickness,8);
putText(main,"Script AA",Point(x+400,y),CV_FONT_HERSHEY_SCRIPT_SIMPLEX,fontScale,Scalar(255,255,255),thickness,CV_AA);
// Save to disk
imwrite("result.png",main);
}
I am new to OpenCV. I appreciate if somebody answers this question. I try to read an image and display it. Below is a copy of the code I copied from documentation. However, a window just pops up without the actual image:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("myimage.jpg", CV_LOAD_IMAGE_UNCHANGED);
if (img.empty())
{
cout << "Error : Image cannot be loaded..!!" << endl;
return -1;
}
else
{
namedWindow("MyWindow", CV_WINDOW_AUTOSIZE);
imshow("MyWindow", img);
waitKey(5000);
}
return 0;
}
I have copied over your code, and changed the image to my local one, and it displays correctly.
Looks like the program cannot read the image for some reason.
Why don't you try with the full path to the image?
The code is pretty correct, make sure you got myimage.jpg in the same folder with your binary.
Try with full path to an image or provide a path to your image as argv[1].
I made a small program that calculates the number of white pixels in a grayscale image. I get different results if I open the image twice in the same program. Same if I display the intensity of the pixels, it changes even if it is the same image. If anyone sees where the problem is please help.
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{ int i=0,j,nbr=0,nbr1=0;
Mat image=imread("2_.png",CV_LOAD_IMAGE_GRAYSCALE);
Mat image2=imread("2_.png",CV_LOAD_IMAGE_GRAYSCALE);
for(i=0;i<image.rows;i++)
{
for( j=0;j<image.cols;j++)
{if (image.at<int>(i,j)!=0)
nbr++;
if (image2.at<int>(i,j)!=0)
nbr1++;
}
}
printf("%d\n %d\n",nbr,nbr1);
return 0;}
Thank you for your help.
It is may be because you need to avoid using int, but uchar for grayscale image. Using int you go out of image memory.
I am trying to convert color images to gray-scale using OpenCV 2.4.11 C++ for Visual Studio 2012. I have used the following code to convert the image to grayscale. However, I am unable to do so because I am not able to read the image.
The message I get is "Error reading image" because img is empty. I have stored the required image in the Debug folder beside the exe file. I have also mentioned the image name as a command argument in the Debug section of the property pages. I am also trying to store the grayscale image in the disk. Thanks in advance. The code is as follows:
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/features2d.hpp"
using namespace cv;
int main(int argc, const char**argv)
{
Mat img=imread("Mountain_8-Bit_Grayscale.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if(img.empty())
{
std::cout<< " --(!) Error reading image " << std::endl;
system("pause");
return -2;
}
namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow"
imshow("MyWindow", img); //display the image which is stored in the 'img' in the "MyWindow" window
imwrite("image_bw.jpg", img);
waitKey(0);
destroyWindow("MyWindow");
return 0;
}
You should try using the absolute path to the image not the relative path. The other steps are fine, the image is read properly and the image displaying and saving commands are given properly there is a path problem.
I'm trying to extract images from gif using giflib in order to bind them in Opencv Mat.
I'm currently using Opencv-2.4.5 and giflib-4.1.6-10.
My problem is that I can extract only extract the first image of the gif.
The second and the others are scratched, I think it is a matter of bits alignement.
Following the doc: http://giflib.sourceforge.net/gif_lib.html
SavedImage *SavedImages; /* Image sequence (high-level API) */
Should provide a pointer to bits of images.
#include <gif_lib.h>
#include <iostream>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int ac, char **av){
int *err;
GifFileType *f = DGifOpenFileName(av[1]);
assert(f != NULL);
int ret = DGifSlurp(f);
assert(ret == GIF_OK);
int width = f->SWidth;
int height = f->SHeight;
cout << f->ImageCount << endl;
cout << width << " : " << height<< endl;
cout << f->SColorResolution << endl;
// SavedImage *image = &f->SavedImages[0]; Does actually works
SavedImage *image = &f->SavedImages[1]; // that compile but the result is a scratched img
Mat img = Mat(Size(width, height), CV_8UC1, image->RasterBits);
imwrite("test.png", img);
DGifCloseFile(f);
return 0;
}
I don't want to use ImageMagick to keep a little piece of code and keep it "light".
Thanks for your Help.
Did you check whether your GIF file is interlaced ? If it is , you should consider it before storing rasterbits into a bitmap format.
Also check the top,left,width and height of the "SavedImages" , every frame does not need to cover all canvas so you should only overwrite pixels that are different from the last frame.