压合细节

诞生于盗版拼接:

实现两幅图片硬生生的压合:

不过还是有问题没有处理到:

第一版:
void myPicAdd(IplImage* src1, IplImage* src2, IplImage* dest){

    for (int i = 0; i< src1->height; i++){
        for (int j = 0; j<dest->widthStep; j++){
            if (j<src1->widthStep)
                dest->imageData[dest->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
            else 
                dest->imageData[dest->widthStep *i + j] = src2->imageData[src2->widthStep *i + j-src1->widthStep];
        }
    }
}

第二版:
IplImage* myPicAdd(IplImage* src1, IplImage* src2){
    //先考虑通道数相同的情况。并且两个高度相同的情况。
    int height = src1->height;
    if (src1->height<src2->height){
        height = src2->height;
    }
    
    IplImage * img = cvCreateImage(cvSize(src1->width + src2->width, height), src1->depth, src1->nChannels);

    if (src1->nChannels == src2->nChannels){
        for (int i = 0; i<src1->height; i++){
            for (int j = 0; j<img->widthStep; j++){
                if (j<src1->widthStep)
                    img->imageData[img->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
                else
                    img->imageData[img->widthStep *i + j] = src2->imageData[src2->widthStep *i + j - src1->widthStep];
            }
        }
    }

    return img;
}

第三版:
IplImage* myPicAdd(IplImage* src1, IplImage* src2){
    //先考虑通道数相同的情况。并且两个高度相同的情况。
    
    IplImage * img = cvCreateImage(cvSize(src1->width + src2->width, src1->height), src1->depth, src1->nChannels);

    if (src1->nChannels == src2->nChannels){
        for (int i = 0; i<src1->height; i++){
            for (int j = 0; j<img->widthStep; j++){
                if (j<src1->widthStep)
                    img->imageData[img->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
                else
                    img->imageData[img->widthStep *i + j] = src2->imageData[src2->widthStep *i + j - src1->widthStep];
            }
        }
    }

    return img;
}

看看这个地方像什么!!!就左边,下面那一块儿

这个就比较好了。所以如果这个地方没有图像的话,应该怎么办,拿黑色填充应该比较好。
第四版:
IplImage* myPicAdd(IplImage* src1, IplImage* src2){
    //先考虑通道数相同的情况。并且两个高度相同的情况。
    int height = src1->height;
    if (src1->height<src2->height){
        height = src2->height;
    }
    IplImage * img = cvCreateImage(cvSize(src1->width + src2->width, height), src1->depth, src1->nChannels);
    if (src1->nChannels == src2->nChannels){
        for (int i = 0; i<height; i++){
            for (int j = 0; j<img->widthStep; j++){
                if (j < src1->widthStep)
                {
                    if (i < src1->height)
                        img->imageData[img->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
                    else
                        img->imageData[img->widthStep *i + j] = 0;
                }
                else
                    img->imageData[img->widthStep *i + j] = src2->imageData[src2->widthStep *i + j - src1->widthStep];
            }
        }
    }
    return img;
}

然后倒过来输出,总是差一个颜色。比如:

这个不对劲啊。

然后后面还有一个:

原图是这个样子的

发现本来是大红的颜色,错了位,并且输出了一个大绿色。

这个明暗度,感觉完全是RGB混了。

或者 根据本来应该是红色变成了绿色。

放大以后可以看到,红色往前走了一位。如果把红色往后推一位。绿色就对上了,所有的东西就应该都对上了。所以结果就是红色提前输出了一位。应该是。红色为什么会提前输出一位呢?
嗯:回到原始版本来解决问题:

void myPicAdd(IplImage* src1, IplImage* src2, IplImage* dest){

    for (int i = 0; i< src1->height; i++){
        for (int j = 0; j<dest->widthStep; j++){
            if (j<src1->widthStep)
                dest->imageData[dest->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
            else 
                dest->imageData[dest->widthStep *i + j+1] = src2->imageData[src2->widthStep *i + j-src1->widthStep];
        }
    }
}

因为发现有一个颜色的错位,所以:上面加深加下划线的地方表示修改。这样两幅图片倒着输出,就没有问题了。

于是 修改:

后面版本的拼接得到:

前后对着的,但是中间的不对劲。

于是在调试过程中继续找到基本版的picAdd

发现果然正过来,有问题。倒着是没问题了,正过来出了问题,结果应该也在+1上。如果去掉必然好使,接下来就在于,为什么?为什么差一个字节,这一个字节的差出现在哪里?

我现在有点儿持盾。。。

正过来:
for (int i = 0; i< src1->height; i++){
        for (int j = 0; j<dest->widthStep; j++){
            if (j<src1->widthStep)
                dest->imageData[dest->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
            else 
                dest->imageData[dest->widthStep *i + j] = src2->imageData[src2->widthStep *i + j-src1->widthStep];
        }
    }

倒过来:
for (int i = 0; i< src1->height; i++){
        for (int j = 0; j<dest->widthStep; j++){
            if (j<src1->widthStep)
                dest->imageData[dest->widthStep *i + j] = src1->imageData[src1->widthStep *i + j];
            else 
                dest->imageData[dest->widthStep *i + j+1] = src2->imageData[src2->widthStep *i + j-src1->widthStep];
        }
    }

都对,不过中间有一条线,为什么会有一条线,所以其实倒过来也不对吧。或者 本身左边有一条线?

左边本不该有一条线的。的确没有,接下来看看右图的右边有没有线,右图的右边也没有线。

平白无故多条线?

-2白线消失 中间加的越多白线越粗,并且 会报出异常。

所以问题出在哪里?!~难道是读取的时候,按照rgb或者bgr的方式读取的?!所以造成了结果的不一致?

结果是-2貌似更正确

虽然有色差,但是中间没有多余的线了。接下来就是 什么时候会多线,为什么会多线?【我靠!!!!刚看见,前面没有了,后面还多一条黄线!!!蒙蔽 蒙蔽 蒙蔽】


我对自己说:先不要弄3通道的,先用1通道的试试。

于是发现了中间多了两条线【因为看了太多次一条线了】。所以忽然想起一个事儿,就是 左边的图是154个像素,右边是156个,刚好差两个像素,所以下次试验这个实验对象也很重要,要不然结果就分析不出来了,差点儿啊~~~下次两幅图片中间的差值,换大一点儿吧。2个像素真的很微妙。所以这样也就为我们实现多图压合,创造了教训。

所以就必须是先左后右,这就是压合顺序。要是先进来的后被压合才奇怪吧。

不过为什么会差一条线呢?!~

心好累,可能已经到了极限了吧,或许同一天做一个事情太久,就会顶了的。

或许需要休息一下了。干点儿别的事情。

今天的问题先记录一下,明天继续处理。

原文地址:https://www.cnblogs.com/letben/p/5462356.html