I am using openCV on C++. In my program I am accessing all the images in a directory using glob function of openCV. And then I am reading and showing the images using imread and imshow functions of openCV.
My image sequence is :
[Black frame - White frame] ---- x50
However the sequence I am getting displayed on screen has some repetition of black frame. I looks like openCV is not reading the files as they are stored in the directory.
Do someone know why this is happening? Did someone encountered similar problem with openCV before?
Here is my code:
void ImageDisp()
{
vector<String> filenames;
String folder = "C:\\Users\\aamir\\Documents\\PythonScripts\\BWSeq_test\\";
glob(folder, filenames);
namedWindow("MyWindow", CV_WINDOW_NORMAL);
cvSetWindowProperty("MyWindow", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
for (size_t i = 0; i < filenames.size() - 1; i++)
{
printf("----------Changing Image--------\n ");
int k = 0;
` Mat img = imread(filenames[i], CV_LOAD_IMAGE_UNCHANGED);
while (k < 100)
{
imshow("MyWindow", img);
waitKey(1);
ShowCursor(false);
k = k + 1;
}
}
destroyWindow("MyWindow");
return 0;
}
Related
This question already has answers here:
OpenCV : imwrite changes the channels pixels values when saving
(1 answer)
Why does loading a jpeg or jpg image changes it upon saving everytime?
(1 answer)
Closed last year.
I'm writing a code like this in c++:
I wish to have a 100% same copy image of test1.jpg.
Unfortunately, I find lots of pixel values change after cv::imwrite.
int main()
{
cv::Mat img1 = cv::imread("./test1.jpg");
cv::imwrite("test2.jpg", img1);
cv::Mat img2 = cv::imread("./test2.jpg");
int count = 0;
for (int i = 0; i < 250; i++) {
for (int j = 0; j < 250; j++) {
if (img1.at<uchar>(i, j) != img2.at<uchar>(i, j)) {
count++;
}
}
}
std::cout << count << std::endl;
return 0;
}
I use count in this program to see how many differences are there between these two images,
although both images (test1.jpg and test2.jpg) have the same size at 46kb, the count's value is as high as 16768!
Is there any method to avoid the change of pixel? I'm only going to use jpg files in the program.
Thanks a lot!
If you want non-lossy compression, you can't use jpg's and have to use a .png (there's .bmp as well but its uncompressed)
jpg = cv.imread("../resources/fisheye/1_1.jpg")
cv.imwrite("1_1.png", jpg)
png = cv.imread("1_1.png")
np.sum(np.where(jpg != png, 1, 0)) # number of differing pixels between images
Output: 0
I am doing a simple reading and displaying PNG image. I am reading a png image with background as transparent. I am converting the image in greyscale and then displaying it. But the converted image is looking something like this:
Original Image:
Greyscale image:
Here is the code. What am I doing wrong?:
Mat image = imread("3X3_a11.png",IMREAD_GRAYSCALE);
Mat output(image.size(),image.type());
// connectedComponents(image, output);
imshow("Output", image);
waitKey(0);
destroyAllWindows();
Your RGBA image is malformed, or at least is very wierd. On loading I see the warning:
libpng warning: iCCP: known incorrect sRGB profile
You can however get the binary version need for cv::connectedComponents with simple processing like:
#include <opencv2\opencv.hpp>
int main()
{
cv::Mat4b img4b = cv::imread("path_to_image", cv::IMREAD_UNCHANGED);
// Convert to grayscale getting rid of alpha channel
cv::Mat1b img(img4b.rows, img4b.cols, uchar(0));
for (int r = 0; r < img4b.rows; ++r) {
for (int c = 0; c < img4b.cols; ++c) {
if (img4b(r, c) == cv::Vec4b(255,255,255,255)) {
img(r, c) = uchar(255);
}
if (img4b(r, c)[3] == 0) {
img(r, c) = uchar(255);
}
}
}
cv::imshow("img", img);
cv::waitKey();
}
Result:
I am trying to copy certain rows from src image to new image called gaps. The gaps image will contain only few rows. However the program crashes at the line with copyTo. The Mat src image is correct, it contains my image because I can view it by imshow().
Mat gaps;
int gap = 6;
for (int r = 0; r < src.rows; r++)
{
if ( r % gap == 0 )
src.row(r).copyTo(gaps.row(r));
}
imshow("gaps", gaps);
waitKey(0);
I am using OpenCV, Visual Studio 2010 C++ on Windows XP.
I tried to add this:
gaps.create(CV_8UC3, 2056,2056); to specify depth and dimensions but it still crashes.
Try this:
// if you want your background to be black --> Scalar(0,0,0)
Mat gaps = Mat(src.size(), src.type(), Scalar(0,0,0));
This is what you'll get, I don't know if that is what you expect/want.
Code
// set your input image
Mat src = imread("{path to input image}");
// your code with the change I proposed
Mat gaps = Mat(src.size(), src.type(), Scalar(0,0,0));
int gap = 6;
for (int r = 0; r < src.rows; r++) {
if ( r % gap == 0 )
src.row(r).copyTo(gaps.row(r));
}
imshow("gaps", gaps);
// create the result image
Mat result = Mat(Size(src.cols * 2, src.rows), src.type(), Scalar(0,0,0));
src.copyTo(result(Rect(0,0,src.cols,src.rows)));
gaps.copyTo(result(Rect(src.cols,0,src.cols,src.rows)));
imshow("result", result);
waitKey();
I am trying to convert different sizes of images from my different folders to the same size as defined in the width and height and them save them in different folder or replace them, I use the function cv::resize for it, and surely imwrite may be use for saving them, but its not working for me, as it showing me error in the parameters of resize.
int count = 0;
int width = 144;
int height = 33;
vector<string>::const_iterator i;
string Dir;
for (i = all_names.begin(); i != all_names.end(); ++i)
{
Dir=( (count < files.size() ) ? YourImagesDirectory_2 : YourImagesDirectory_3);
Mat row_img = cv::imread( Dir +*i, 0 );
cv::resize(row_img , width , height);
imwrite( "D:\\TestData\\img_resize.jpg", img_resize );
++count;
}
After resize this function :
imwrite( "D:\\TestData\\img_resize.jpg", img_resize );
Only save one image to my folder test , i want all of them in my folder
Here is an example for how to resize an image:
Mat img = imread("C:\\foo.bmp");
Mat img_resize;
resize(img, img_resize, Size(144, 33));
EDIT:
Supposed that you have several images named as image001.jpg, image002.jpg, image003.jpg, image004.jpg, image005.jpg..., and want to save them after resizing. Hopes the following code works it out.
#include <cv.h>
#include <highgui.h>
using namespace cv;
char pathLoading[255];
char pathSaving[255];
char num[10];
char jpg[10] = ".jpg";
int counter = 1;
int main(int argc, char** argv) {
while (1) {
if (counter < 6) {
// To load 5 images
strcpy(pathLoading, "c:\\image");
sprintf(num, "%03i", counter);
strcat(pathLoading, num);
strcat(pathLoading, jpg);
Mat image = imread(pathLoading);
Mat image_resize;
resize(image, image_resize, Size(144, 33));
// To save 5 images
strcpy(pathSaving, "c:\\image_resize");
sprintf(num, "%03i", counter);
strcat(pathSaving, num);
strcat(pathSaving, jpg);
imwrite(pathSaving, image_resize);
counter++;
}
}
return 0;
}
Here is the way through which i can csave multiple images in the folder :
for (i = all_names.begin() ; i!= all_names.end() ; i++)
{
Dir=( (count < files.size() ) ? YourImagesDirectory : YourImagesDirectory_2);
Mat row_img = cv::imread(Dir+*i );
//imshow ("show",row_img);
Mat img_resize;
resize(row_img, img_resize, Size(144, 33));
Mat img = img_resize;
sprintf(buffer,"D:\\image%u.jpg",count);
imwrite(buffer,img);
//imwrite("D:\\TestData\\*.jpg" , img_resize);
count++;
}
Use the functions :
sprintf(buffer,"D:\\image%u.jpg",count);
imwrite(buffer,img);
For giving directory , name and imwrite for saving there
If the only goal is to resize the images I would guess it would be simpler to use dedicated software with batch processing capability, e.g. IrfanView.
If this is programming exercise, nevermind my answer and look at answers by other people.
HINT: You are saving all your images with single filename, thus effectively rewriting the previously converted images with the new ones.
I'm having difficulties using ROI using opencv c++.
I have a sequence of images which are stored in a vector. The vector image contained big blob and small blob. I want to remove the small blobs for every vector image. However, there is something wrong with the output result where if the small blobs in current vector image was removed, it will affect the blobs region for the next vector image (and previous vector image). Is there something wrong with ROI opencv c++? Below is sample code:
vector<Mat> finalImg;
for(unsigned int i = 0 ; i < srcImg.size(); i++) {
vector<vector<Point> > contoursFinal;
vector<Vec4i> hierarchyFinal;
Mat tempV_img;
srcImg[i].copyTo(tempV_img);
cv::findContours( tempV_img, contoursFinal, hierarchyFinal, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0,0) );
for(unsigned int j = 0; j < contoursFinal.size(); j++) {
Rect r = cv::boundingRect( contoursFinal[j] );
int heightChar = r.height;
/// Set image region of interest
cv::Rect ROI(r.x-1, r.y-1, r.width+2, r.height+2);
Mat srcImg_crop = srcImg[i](ROI);
cv::namedWindow("cropImg (bf)", 0);
cv::imshow("cropImg (bf)", srcImg_crop);
if(heightChar < srcImg[i].rows*0.90){
srcImg_crop.setTo(0);
}
cv::namedWindow("cropImg (af)", 0);
cv::imshow("cropImg (af)", srcImg_crop);
cv::waitKey(0);
if(cv::countNonZero(srcImg_crop) != 0) {
finalImg.push_back(srcImg_crop);
}
srcImg_crop.release();
}
cv::namedWindow("Sorted Final", 0);
cv::imshow("Sorted Final", finalImg[i]);
cv::waitKey(0);
contoursFinal.clear();
hierarchyFinal.clear();
}
Sorry all,
I just figured it out. Below shows the trick.
vector<Mat> tempV;
tempV.clear();
for(unsigned int i = 0 ; i < srcImg.size(); i++) {
Mat temp;
srcImg[i].copyTo(temp);
tempV.push_back(temp);
temp.release();
}
Instead of using srcImg[i]. I replace it with a new vector tempV[i]. Then it will not affect the previous as well as next vector image.