cv2.fillPoly 相交多边形失败

Índ*_*dio 7 python opencv

我的目标是填充几个简单的四边形,但是一些相交的多边形之间的一些孔/补丁未填充。

代码

import cv2
import numpy as np

bboxes = [
    np.array([126., 615., 141., 615., 141., 640., 126., 640., 140., 615., 157., 615., 157., 640.,  140., 640., 158., 615., 174., 616., 174., 640., 158., 640.]),
    np.array([193., 616., 209., 616., 209., 640., 193., 640., 209., 616., 225., 616., 225., 640.,  209., 640.]),
    np.array([242., 613., 258., 613., 259., 640., 242., 640., 259., 615., 276., 615., 276., 640.,  260., 640., 275., 622., 291., 622., 291., 646., 275., 646., 292., 615., 308., 615.,  309., 640., 292., 640., 308., 616., 325., 616., 325., 640., 309., 640.]),
    np.array([126., 656., 143., 656., 143., 681., 126., 681., 143., 662., 158., 662., 159., 681.,  143., 681., 158., 662., 174., 663., 174., 681., 159., 681., 174., 663., 189., 663.,  189., 681., 174., 681., 188., 663., 205., 663., 205., 681., 188., 681., 206., 653.,  222., 653., 222., 681., 206., 681., 222., 653., 238., 653., 239., 681., 222., 681.]),
    np.array([256., 657., 274., 657., 274., 681., 256., 681., 275., 663., 290., 663., 291., 681.,  275., 681., 292., 663., 307., 663., 307., 682., 293., 681., 305., 657., 321., 657.,  321., 682., 305., 682., 321., 656., 337., 656., 338., 682., 321., 682., 338., 663.,  353., 663., 353., 682., 338., 682.]),
    np.array([126., 697., 143., 697., 143., 722., 127., 722., 143., 697., 159., 697., 159., 722.,  143., 722., 159., 697., 175., 697., 175., 722., 159., 722., 175., 697., 191., 697.,  191., 722., 175., 722., 190., 697., 208., 698., 208., 722., 190., 722., 209., 698.,  225., 698., 226., 722., 209., 722., 225., 698., 242., 698., 242., 722., 226., 722.,  242., 698., 258., 698., 258., 723., 242., 722., 258., 698., 274., 698., 275., 723., 258., 723., 274., 698., 291., 698., 291., 723., 275., 723., 290., 698., 307., 698.,  307., 723., 290., 723., 308., 698., 325., 698., 325., 723., 308., 723., 324., 698.,  342., 698., 342., 723., 324., 723., 342., 698., 361., 698., 361., 723., 342., 723.,  361., 698., 378., 698., 378., 723., 361., 723.]),
    np.array([398., 699., 414., 699., 415., 724., 398., 723., 414., 699., 431., 699., 431., 724.,  415., 724., 431., 696., 446., 696., 447., 730., 431., 730., 446., 699., 463., 699.,  464., 724., 447., 724., 463., 699., 480., 699., 480., 724., 464., 724.]),
    np.array([126., 738., 143., 738., 143., 763., 126., 763., 142., 738., 162., 738., 162., 763.,  142., 763., 163., 738., 180., 738., 180., 763., 163., 763., 185., 745., 192., 745.,  192., 763., 185., 763.]),
    np.array([206., 739., 223., 739., 223., 764., 207., 763., 223., 739., 239., 739., 239., 764.,  223., 764., 238., 739., 255., 739., 256., 764., 238., 764.]),
    np.array([268., 548., 283., 548., 283., 565., 268., 565., 286., 541., 302., 541., 303., 557.,  286., 557., 305., 535., 323., 535., 323., 560., 306., 560., 326., 534., 344., 534.,  345., 558., 326., 558., 346., 534., 365., 534., 365., 557., 347., 557., 366., 534.,  385., 533., 386., 559., 366., 559., 387., 537., 417., 536., 418., 562., 388., 562.,  418., 541., 438., 540., 438., 566., 419., 566., 433., 551., 451., 551., 452., 579., 433., 579.]),
    np.array([ 20.,  69.,  51.,  69.,  51., 113.,  20., 113.,  56.,  68.,  65.,  68.,  65., 112.,   56., 112.,  61.,  67.,  86.,  67.,  86., 113.,  61., 113.,  85.,  68., 117.,  67.,  117., 111.,  85., 112.]),
    np.array([152.,  66., 169.,  65., 169., 109., 153., 110., 169.,  64., 193.,  64., 193., 110.,  169., 110.]),
    np.array([225.,  58., 250.,  57., 250., 108., 225., 109., 251.,  60., 262.,  60., 262., 107.,  251., 107., 261.,  72., 286.,  71., 286., 117., 261., 118., 287.,  59., 298.,  59.,  298., 106., 287., 106., 299.,  62., 317.,  61., 317., 107., 299., 107.]),
    np.array([ 24., 138.,  62., 137.,  62., 181.,  24., 182.,  61., 134.,  72., 134.,  72., 181.,   61., 181.,  71., 145.,  93., 145.,  93., 181.,  71., 182.,  95., 130., 118., 129.,  118., 180.,  95., 180., 116., 144., 141., 144., 141., 180., 116., 181., 143., 129.,  156., 129., 156., 181., 143., 181., 156., 129., 169., 128., 169., 181., 156., 181.,  167., 143., 191., 142., 192., 179., 167., 180.]),
    np.array([227., 133., 255., 132., 256., 177., 228., 177., 254., 142., 278., 141., 279., 177.,  255., 178., 278., 140., 302., 140., 303., 176., 279., 176., 302., 131., 320., 130.,  321., 176., 303., 177.]),
    np.array([ 22., 206.,  48., 206.,  48., 250.,  22., 251.,  48., 205.,  71., 204.,  71., 250.,   48., 250.,  71., 204.,  94., 204.,  94., 250.,  71., 251.,  94., 204., 118., 203.,  118., 249.,  94., 249., 118., 203., 141., 203., 141., 249., 118., 249., 141., 203.,  164., 202., 164., 249., 141., 250., 165., 202., 188., 202., 188., 249., 165., 249.,  187., 203., 211., 202., 211., 247., 187., 248., 211., 202., 235., 202., 235., 247., 211., 247., 236., 201., 259., 200., 259., 247., 236., 248., 258., 202., 282., 201.,  282., 246., 258., 246., 282., 200., 306., 200., 307., 246., 282., 247., 306., 200.,  330., 199., 331., 246., 307., 246., 331., 199., 356., 198., 356., 246., 332., 246.,  355., 200., 381., 199., 381., 244., 355., 245., 382., 198., 405., 197., 406., 245.,  382., 245.]),
    np.array([439., 197., 462., 196., 463., 244., 440., 244., 461., 197., 485., 197., 486., 243.,  462., 244., 481., 191., 505., 190., 507., 253., 482., 253., 510., 195., 533., 195.,  534., 242., 510., 243., 534., 196., 552., 195., 553., 241., 535., 241.]),
    np.array([ 23., 274.,  51., 274.,  51., 320.,  23., 321.,  48., 275.,  79., 274.,  79., 319.,   48., 320.,  82., 273., 110., 273., 110., 320.,  82., 320., 110., 284., 121., 284.,  121., 319., 110., 320.]),
    np.array([153., 273., 170., 273., 171., 318., 154., 318., 170., 272., 193., 271., 194., 318.,  171., 319., 193., 272., 210., 272., 211., 317., 194., 317.]),
    np.array([ 25., 335.,  45., 334.,  45., 364.,  25., 365.,  45., 344.,  61., 344.,  61., 364.,   45., 364.,  63., 344.,  78., 344.,  78., 364.,  63., 364.,  77., 336.,  87., 336.,   87., 364.,  77., 364.,  86., 334., 106., 334., 106., 364.,  86., 364., 106., 337.,  124., 336., 124., 363., 106., 364., 124., 336., 142., 336., 142., 363., 124., 363.,  143., 336., 174., 336., 174., 369., 143., 369., 168., 335., 184., 335., 184., 370., 168., 370., 189., 343., 205., 342., 205., 362., 189., 363., 206., 342., 231., 342.,  231., 362., 206., 362., 231., 342., 247., 342., 247., 362., 231., 362., 245., 342.,  260., 342., 260., 362., 245., 362., 262., 349., 271., 348., 271., 351., 262., 352.,  265., 333., 281., 333., 281., 368., 265., 369., 286., 341., 302., 341., 303., 361.,  286., 361., 303., 341., 319., 341., 319., 361., 304., 361., 319., 331., 337., 330.,  337., 361., 319., 361., 335., 341., 350., 340., 350., 361., 335., 361., 352.,340.,  368., 340., 369., 360., 352., 361., 368., 340., 386., 340., 386., 360., 369., 360.,  385., 356., 391., 356., 391., 361., 385., 361., 392., 340., 408., 340., 409., 360.,  392., 360., 407., 329., 428., 329., 428., 360., 408., 360., 430., 339., 447., 339.,  448., 359., 430., 360.]),
    np.array([100., 398., 158., 397., 158., 451., 101., 452., 163., 401., 210., 401., 211., 451.,  163., 451., 212., 399., 245., 399., 246., 450., 213., 450., 245., 399., 279., 399.,  279., 449., 246., 450., 276., 439., 292., 439., 292., 458., 276., 459., 293., 400.,  341., 399., 341., 450., 293., 450., 343., 393., 384., 393., 385., 453., 343., 453.,  382., 438., 398., 438., 399., 458., 382., 458., 398., 398., 445., 397., 446., 450., 398., 451., 446., 398., 495., 398., 495., 449., 447., 449.]),
    np.array([346.,  59., 382.,  58., 383., 142., 347., 143., 377.,  97., 420.,  96., 421., 146.,  377., 147., 420.,  86., 447.,  85., 448., 147., 421., 148., 449.,  64., 478.,  64.,  479., 148., 450., 148., 479.,  96., 512.,  95., 513., 146., 480., 147., 511.,  91.,  554.,  90., 556., 172., 512., 173., 543.,  50., 586.,  49., 588., 155., 545., 156.]),
    np.array([246., 817., 257., 817., 257., 831., 246., 831., 256., 817., 269., 817., 269., 831.,  256., 831., 268., 817., 284., 817., 284., 832., 268., 831., 285., 817., 298., 817.,  298., 832., 285., 832., 298., 812., 312., 812., 313., 836., 298., 836., 313., 817.,  326., 818., 326., 837., 314., 837., 325., 812., 338., 812., 338., 832., 325., 832.,  338., 818., 352., 818., 352., 832., 338., 832., 352., 818., 364., 818., 364., 833., 352., 832., 368., 828., 374., 829., 374., 833., 368., 833., 369., 818., 382., 818.,  382., 833., 369., 833., 384., 818., 395., 818., 395., 833., 384., 833., 393., 818.,  407., 818., 407., 833., 393., 833., 407., 818., 420., 819., 420., 839., 407., 838.,  424., 829., 430., 829., 430., 833., 424., 833., 425., 819., 439., 819., 439., 833.,  426., 833., 439., 814., 452., 814., 453., 834., 439., 833., 452., 812., 466., 812.,  466., 834., 453., 834.]),
]

canvas = np.zeros((800, 650))

for cbbs in bboxes:

    cbbs = cbbs.astype(np.int32)
    cbbs = cbbs.reshape((-1, 4, 2))

    cv2.fillPoly(img=canvas, pts=cbbs, color=255, lineType=cv2.LINE_AA)

cv2.imwrite("out_fillPoly.png", canvas)
Run Code Online (Sandbox Code Playgroud)

产量

在此输入图像描述

但是,通过将调用更改cv2.fillPoly

for cbb in cbbs:
    cv2.fillPoly(img=img, pts=[cbb], color=255)
Run Code Online (Sandbox Code Playgroud)

使四边形相互重叠,从而产生预期的输出

在此输入图像描述

然而,在更高的总体运行时间下,每个图像多边形更多。

文档表明这种行为不是预期的。

是否有更有效(更快)的解决方案来解决这个问题?

PS:我也试过了cv2.drawContours,结果是一样的。

以上均已在python 3.8.10和上进行了测试opencv 4.5.3