简体   繁体   中英

OpenCV resizing and cropping image according to pixel value

#include "iostream"
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include "cxmisc.h"
#include "math.h"

using namespace cv;
using namespace std;

int main(){

int height, width, x, y, i, minX, minY, maxX, maxY;
char imgFileName[100];


IplImage *origImage = cvLoadImage("BaybayinMark/b9.jpg", -1);
height = origImage->height;
width = origImage->width;

IplImage *grayImage = cvCreateImage(cvSize(width, height), 8, 1);
IplImage *binImage = cvCreateImage(cvSize(width, height), 8, 1);


//Pre-processing phase


cvCvtColor(origImage, grayImage, CV_BGR2GRAY);
cvDilate(grayImage, grayImage, NULL, 1);
cvSmooth(grayImage, grayImage, CV_GAUSSIAN, 21, 21, 0, 0);
cvThreshold(grayImage, binImage, 120, 255, CV_THRESH_BINARY);
cvNormalize(binImage,binImage,0,1,CV_MINMAX);

minX = width;
minY = height;
maxX = 0;
maxY = 0;


CvScalar s;


for (x=0; x<width-1; x++){
for(y=0; y<height-1; y++){
    s = cvGet2D(binImage, y, x);
    //printf("%f\n", s.val[0]);
    if (s.val[0] == 1){
        //printf("HELLO");
        minX = min(minX, x);
        minY = min(minY, y);
        maxX = max(maxX, x);
        maxY = max(maxY, y);

    }   
}
}

cvSetImageROI(binImage, cvRect(minX, minY, maxX-minX, maxY-minY));

IplImage *cropImage = cvCreateImage(cvGetSize(binImage), 8, 1);

cvCopy(binImage, cropImage, NULL);

cvSaveImage("crop/cropImage9.jpg", cropImage);
cvResetImageROI(binImage);

cvReleaseImage(&origImage);
cvReleaseImage(&binImage);

cvReleaseImage(&grayImage);
cvReleaseImage(&cropImage);

}

Hi! i just want to ask about this code. I am trying to identify the outermost edges of an image and crop the image according them. All I was having after running was a black image with the same size. Am I trying to do it the wrong way? Please enlighten me I'm a beginner with OpenCV.

In the rush of finding what -the-heck-is-the-problem people tend to forget a more important question: how -the-heck-do-i-find-the-problem .

With image processing applications, the how can be answered by the poor man's debugger in OpenCV, which is adding cvSaveImage() calls through the code to be able to visualize what every step of the way is doing:

    //Pre-processing phase
    cvCvtColor(origImage, grayImage, CV_BGR2GRAY);
    cvSaveImage("cv_color.jpg", grayImage);

    cvDilate(grayImage, grayImage, NULL, 1);
    cvSaveImage("cv_dilate.jpg", grayImage);

    cvSmooth(grayImage, grayImage, CV_GAUSSIAN, 21, 21, 0, 0);
    cvSaveImage("cv_smooth.jpg", grayImage);

    cvThreshold(grayImage, binImage, 120, 255, CV_THRESH_BINARY);
    cvSaveImage("cv_threshold.jpg", binImage);

    cvNormalize(binImage,binImage,0,1,CV_MINMAX);
    cvSaveImage("cv_normalize.jpg", binImage);

This code reveals that the resulting image gets black even before your custom for loop, and the call that is responsible for that is cvNormalize() . But it makes sense right? You are converting pixels which are in the range [0..255] to values of 0 and 1.

So the problem is that at the end of your processing, when you save the resulting image to the dislk, you forgot to normalize the values back to the original range :

    IplImage *cropImage = cvCreateImage(cvGetSize(binImage), 8, 1);
    cvCopy(binImage, cropImage, NULL);

    cvNormalize(cropImage, cropImage, 0, 255, CV_MINMAX);

    cvSaveImage("result.jpg", cropImage);

And that solves the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM